Tutorial

How To Create a Dark-Mode Theme Using CSS Variables

Updated on September 24, 2020
authorauthor

Alligator.io and Matt Abrams

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 authors
Default avatar
Alligator.io

author



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


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!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

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.