Adding a Dark/Light Mode Switch to Your Site (using CSS Variables and JavaScript)

A theme switch at the touch of a button

My last three posts have been rather focused on functionality, so now let’s switch gears a little and discuss how to implement a quality-of-life CSS feature… offering an easy choice of a light or dark mode for your site.

This tutorial is going to make use of CSS Variables and some JavaScript, most notably the localstorage feature which will make the user’s choice persist across visits without the use of cookies.

First off, let’s create our button and place it on the page somewhere. Mine is in a footer, but it could just as easily reside in a sidebar or anywhere else.

<button id="switch" onclick="toggleTheme()"><div id="switchText"></div></button>

Nice and simple. A button with an id of ‘switch’ and an onclick function of ‘toggleTheme()’, then inside it an empty div with an id of ‘switchText’ – this is so that we can automatically fill the appropriate text for the switcher based on the current theme.

Next up, let’s hop over to the CSS and take a look at CSS variables.

html, body {
    background-color: var(--color-secondary);
    color: var(--font-color);
  }
  
  .theme-light {
    --color-primary: #ede4da;
    --color-secondary: #deccb1;
    --color-accent: #d99f45;
    --font-color: #1a1918;
    --color-highlight: #32acb3;
    --color-shadow: #4a4a46;
  }
  .theme-dark {
    --color-primary: #1c1a1a;
    --color-secondary: #423438;
    --color-accent: #a34646;
    --font-color: #e9f5f4;
    --color-highlight: #b0932a;
    --color-shadow: #68695e;
  }

In this code block we set the background-color and color as, not set color values, but as variables with the syntax var(–variablename). We then go into classes for theme-light and theme-dark, and set a palette of variables in each.

Now, all that’s left is to add some JavaScript functionality to do a few things:

  • Determine the theme to be used onload (this one defaults to dark)
  • Add the functionality to press the button and switch from one theme to the other
  • Set the text of the button to reflect which mode it will switch to when pressed
  • Make the browser remember the user’s choice in some capacity (without using cookies)

All of this can be accomplished with the following code block:

// function to set a given theme/color-scheme
function setTheme(themeName) {
    localStorage.setItem('theme', themeName);
    document.documentElement.className = themeName;
}

// function to toggle between light and dark theme
function toggleTheme() {
   if (localStorage.getItem('theme') === 'theme-dark'){
       setTheme('theme-light');
   } else {
       setTheme('theme-dark');
   }
   setSwitchText();
}

// Function to set the text of the toggle button
function setSwitchText() {
	if (localStorage.getItem('theme') === 'theme-light') {
		document.getElementById("switchText").innerHTML = "Dark Theme";
	} else {
		document.getElementById("switchText").innerHTML = "Light Theme";
	}
}

// Immediately invoked function to set the theme on initial load
(function () {
   if (localStorage.getItem('theme') === 'theme-light') {
       setTheme('theme-light');
   } else {
       setTheme('theme-dark');
   }
   setSwitchText();
})();

All that done, you should now have a page that will switch between light and dark modes, as well as remember the user’s choice with localstorage. Easy peasy.

EDIT 5/30/2020 – Fixed a minor error where the setSwitchText() function is not invoked on initial load, resulting in a blank button.

Leave a Reply

Your email address will not be published. Required fields are marked *