CSS and JS Dark and Light Mode Feature

How to Make CSS Dark and Light Mode Feature?

In this tutorial, you will learn how to implement dark and light mode toggle feature to a website using CSS, and JavaScript.

What is the way to build dark and light mode functionality?

It is up to you how you can build it. Here I will show you one of the best ways to do that which is – Using CSS custom properties.

First, we define the colors for the light mode to the CSS custom properties. Like the following –

:root {
  --color:#222222;
  --bg-color:#f7f7f7;
  --main-bg-color:white;
}

After that, we have to define colors for the dark mode in the same custom properties, but this time the selector will be the same but with the [dark-theme] attribute.

:root[dark-theme] {
  --color:#cccccc;
  --bg-color:#1a1a1a;
  --main-bg-color:#111111;
}

So the colors have been defined, now if you set the dark-theme attribute on the root element (<html>), the :root[dark-theme] color will be applied to the entire website.

dark-theme attribute on the root element

You can dynamically set this dark-theme attribute to the root element by using following JavaScript code –

document.documentElement.setAttribute('dark-theme',true);

Example of dark and light mode

HTML CSS and JavaScript Dark and Light Mode example
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Dark and Light Mode Example</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@700&display=swap" rel="stylesheet">
    <style>
        *,
        *::before,
        *::after {
            box-sizing: border-box;
            line-height: 1.5em;
        }

        :root {
            --color: #222222;
            --bg-color: #f7f7f7;
            --main-bg-color: white;
        }

        :root[dark-theme] {
            --color: #cccccc;
            --bg-color: #1a1a1a;
            --main-bg-color: #111111;
        }

        html {
            font-size: 16px;
            -webkit-text-size-adjust: 100%;
        }

        body {
            margin: 0;
            padding: 20px;
            overflow-wrap: break-word;
            font-family: "Open Sans", sans-serif;
            color: var(--color);
            background-color: var(--bg-color);
            -moz-osx-font-smoothing: grayscale;
            -webkit-font-smoothing: antialiased;
        }

        main {
            max-width: 900px;
            margin: 0 auto;
            background-color: var(--main-bg-color);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
                0 4px 6px -4px rgba(0, 0, 0, 0.1);
            padding: 30px;
            border-radius: 3px;
        }

        h1 {
            text-align: center;
            font-size: 2rem;
        }

        .change-theme-btn {
            text-align: center;
        }
        .change-theme-btn button {
            all: unset;
            font-size: 5rem;
            cursor: pointer;
            border: 1px solid;
            padding: 10px;
            border-radius: 50%;
            overflow: hidden;
        }
        .change-theme-btn button.light .sun {
            visibility: hidden;
        }
        .change-theme-btn button.dark .moon {
            visibility: hidden;
        }
        .change-theme-btn button.dark .sun {
            visibility: visible !important;
        }
    </style>
</head>
<body>
    <main class="container">
        <h1>Dark and Light Mode</h1>
        <div class="change-theme-btn">
            <button id="themeChanger" class="light"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon"><path class="moon" d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/><g class="sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></g></svg></button>
        </div>
    </main>

    <script>
        const themeChanger = document.getElementById('themeChanger');

        themeChanger.onclick = function(){
            themeChanger.classList.toggle("dark");
            document.documentElement.toggleAttribute('dark-theme');

            if(themeChanger.classList.contains('dark')){
                localStorage.setItem('theme','dark');
                return;
            }
            localStorage.setItem('theme','light')
        }

        window.onload = function(){
            const theme = localStorage.getItem('theme');
            if(theme && theme === 'dark'){
                themeChanger.classList.add('dark');
                document.documentElement.setAttribute('dark-theme',true);
            }
        }
    </script>
</body>
</html>