Report this

What is the reason for this report?

How To Create a Dark-Mode Theme Using CSS Variables

Updated on September 24, 2020
How To Create a Dark-Mode Theme Using CSS Variables

Introduction

You may have noticed that on many websites you can now toggle between dark and light themes. This is often done using CSS custom properties (aka CSS variables). In this tutorial you’ll see how you can achieve something similar using only CSS and a touch of JavaScript. To learn more about how this code works, check out our series content on Javascript or HTML.

Step 1 — Creating the CSS Variables

The power of custom properties in CSS really shines here because, unlike with variables defined using a CSS preprocessor, these values are dynamic; their values can be changed or overwritten at any point in time in response to user input. When the value of a variable is changed or overwritten, all elements that use the variable will automatically reflect the change.

First you’ll have to do a bit of work and extract all the colors that you want to use in your CSS custom properties. Let’s say you’re starting with the following styles:

style.css
body {
  background: white;
  color: #555;
}

a, a:link {
  color: #639A67;
}
a:hover {
  color: #205D67;
}

You’ll then define the custom properties as such:

style.css
:root {
  --bg: white;
  --text-color: #555;
  --link-color: #639A67;
  --link-hover: #205D67;
}

With this in place, you can now change your CSS rules to something like the following:

style.css
body {
  background: var(--bg);
  color: var(--text-color);
}

a, a:link {
  color: var(--link-color);
}
a:hover {
  color: var(--link-hover);
}

Applying the theme involves adding a class to the body element, so you’ll define the theme’s colors under that class name. Here we’ll call the class funky. Simply make sure to define an override color for all colors should change:

style.css
.funky {
  --bg: hotpink;
  --text-color: white;
  --link-color: #B793E6;
  --link-hover: #3532A7;
}

Step 2 — Adding Fallbacks for Older Browsers

Support for CSS custom properties is pretty good, but you’ll most likely want to include fallbacks for users that are on older browsers.

Let’s say that we have an element that should have a linear-gradient background with colors defined as custom properties. You provide hard-coded colors first, and older browsers will ignore the version that they don’t understand:

style.css
background: linear-gradient(to right, #FFFB85, #5A3662); /* our fallback */
background: linear-gradient(to right, var(--top-grad1), var(--top-grad2));

Step 3 — Toggling Our Theme

We only need a very minimal amount of JavaScript to add an event listener on an element that acts as the toggle button between the two themes.

Here the toggle button has the toggle-theme class and we use document.querySelector to get a reference to that element:

app.js
let toggle = document.querySelector('.toggle-theme');

toggle.addEventListener('click', function(e) {
  e.preventDefault();

  if (document.body.classList.contains('funky')) {
    // Turning the theme off:
    document.body.classList.remove('funky');
    // Reverse logic on the button text, so that users can turn
    // the theme back on:
    toggle.innerText = 'Turn theme on';
  } else {
    document.body.classList.add('funky');
    toggle.innerText = 'Turn theme off';
  }
});

This does the trick to toggle between the two themes. We can do better and also add/remove an item to localStorage at the same time so that our theme gets applied automatically when the page loads:

app.js
let toggle = document.querySelector('.toggle-theme');

// Turn the theme off if the 'funky' key exists in localStorage
if (localStorage.getItem('funky')) {
  document.body.classList.add('funky');
  toggle.innerText = 'Turn theme off';
}

toggle.addEventListener('click', function(e) {
  e.preventDefault();

  if (document.body.classList.contains('funky')) {
    document.body.classList.remove('funky');
    toggle.innerText = 'Turn theme on';
    localStorage.removeItem('funky');
  } else {
    document.body.classList.add('funky');
    toggle.innerText = 'Turn theme off';
    localStorage.setItem('funky', true);
  }
});

You can use this small snippet and CSS variables to create themed websites like this, with dark-modes, light-modes, and more.

Conclusion

In this tutorial you created a themed website that has a dark and light mode. To learn more about how this code works, check out our series content on Javascript or HTML.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Alligator
Alligator
Author
See author profile

Alligator.io is a developer-focused resource that offers tutorials and insights on a wide range of modern front-end technologies, including Angular 2+, Vue.js, React, TypeScript, Ionic, and JavaScript.

Matt Abrams
Matt Abrams
Editor
See author profile

Supporting the open-source community one tutorial at a time. Former Technical Editor at DigitalOcean. Expertise in topics including Ubuntu 22.04, Ubuntu 20.04, CentOS, and more.

Category:
Tags:

Still looking for an answer?

Was this helpful?


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.