Steps for choosing how to switch your website theme (dark/light mode):

  1. Theme change element
  2. Theme styling
    • create separate styling sheets (CSS files)
    • or use CSS variable names and define different styles in a single CSS file
  3. JavaScript
    • code the function that connects the "element" on your page and the styling
  4. Ideas and considerations
  5. Final notes

The switch button

I use a button for switching themes, alternatively you can use a toggle or a drop down list. You can start with a simple button with text and improve on it later.

I use filled sun and moon SVG icons by bootstrap and change the SVG path (shape) with javaScript. I also liked their lamp and lightbulbs which you can find here. I prefer SVGs because they are light-weight and don't lose their quality.

You need to set an id for the SVG path so you can change it using setAttribute when the button is clicked.

Do not forget to set an id for the theme button so that it can be selected by JS querySelector.


Multiple theme styles in a single CSS file

Theme toggle can switch between CSS files, but in this case, all the styling is done with one CSS file. The colors are defined with CSS variables in the root and the dark theme colors are defined in root with a class named dark-theme. The default style is light. The JavaScript function adds a class (dark-theme) to body so that the dark-theme styling defined in the CSS file is applied.

The top of your CSS file would look like the following and you can notice that if a variable is not defined in the dark-theme (for example the font), the values from the default theme will apply.

:root {
          --text-font: "Lato", sans-serif;
          --text-color: black
          --background-color: white
        }
                  
        :root .dark-theme {
          --text-color: white;
          --background-color: black;
        }

If the style is already dark, the function removes the dark-theme class so that only the default styling is applied.


JavaScript code for switching themes

The JavaScript toggleTheme function has an if statement that is called when the switch button is clicked. The variable inside the if function needs to be defined beforehand.

var theme = "light-theme";

I used bootstrap navbar so I had a style class added to the navbar in the dark-mode. I also assigned an id to the button's SVG path and it changes from sun to moon with the theme switch.

Based on your design, you can add or remove the changes that happen. In the following code, whatever is inside the if happens during the dark theme and the code inside the else is executed in the light theme.

LocalStorage is for storing the theme preference in multi-page websites and for future visits.

function toggleTheme() {
          if (theme === "light-theme") {
            theme = "dark-theme";
            localStorage.setItem("activeTheme", "dark theme activate");
            document.querySelector("body").classList.add("dark-theme");
            document.querySelector("nav").classList.add("navbar-dark");
            document
              .getElementById("theme-icon-path")
              .setAttribute(
                "d",
                "M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"
              );
          } else {
            theme = "light-theme";
            localStorage.setItem("activeTheme", "dark theme NOT activate");
            document.querySelector("body").classList.remove("dark-theme");
            document.querySelector("nav").classList.remove("navbar-dark");
            document
              .getElementById("theme-icon-path")
              .setAttribute(
                "d",
                "M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"
              );
          }
        }
        
        var theme = "light-theme";
        let themeButton = document.querySelector("#theme-icon");
        themeButton.addEventListener("click", toggleTheme);

Ideas and considerations

  • Set active theme for multi-page websites
  • I stored the theme status in the local storage so that if it has been switched on another page, the status is accessible on other pages. My default theme is light, so the function switches to dark mode if it has been activated on any other page.

    let onAnotherPage = localStorage.getItem("activeTheme");   
            if (onAnotherPage === "dark theme activate") {  
              toggleTheme();            
            }
  • Do not blind dark theme users with a white background
  • With the following JS code, you can check if the user's system theme is dark mode:

    const userPrefersDarkTheme = window.matchMedia('(prefers-color-scheme: dark)');

    Because my default theme on load is light, I inserted an if function that switched to dark theme when the user's system default is dark. The switch button works fine and the user can switch it back to light mode.

    if (userPrefersDarkTheme.matches) {
              toggleTheme();
            }

    Final notes

    This article gives an overview of my thought process and how I created the theme switch. Please give attribution if you use any parts of the code or this article.

    I would love to hear from you if you think your thoughts can improve this article or if you just want to chat.