DEV Community

Cover image for Using CSS variables to create a dark mode for your site

Using CSS variables to create a dark mode for your site

Charanjit Chana
👨‍💻 Head of Development 💪 Progressive Enhancement FTW!
Originally published at ・3 min read

These days, building a dark theme is easy thanks to media queries. Change the preferences on your computer of phone and see this page change from light mode to dark and back again

body {
    background-color: white;

@media (prefers-color-scheme: dark) {
    body {
        background-color: black;
Enter fullscreen mode Exit fullscreen mode

This is how I’ve done it all for a couple of years, it’s simple and effective but it can also be a pain to maintain if you have a large amount of CSS to work with. I’ve been using a combination of LESS and SCSS for over a decade so variables was the obvious way to make this all more manageable.

As I was rebuilt my portfolio, something that requires around 400 lines of uncompressed CSS, I realised just how much effort was going into overwriting colours to cater for dark mode. I just knew there was a better way to do it than overwriting each colour, even with the benefit of SASS behind me.

CSS variables to the rescue!

As part of the original review process for SITEJOY I was inspecting a lot of CSS and kept coming across CSS variables where they were used just to specify the colours used on the site. Without any thought, it seemed odd given you could achieve the same with pre-processors, but then it hit me.

Whether it's dark mode specifically or for creating themes, using CSS variables means I only need to change the colour values. I no longer need to redeclare selectors and properties for overwriting, CSS variables take care of it all! (I know, I know, it's really obvious when you think about it)

Examples on Codepen

I've got three examples to explain my journey, you can test them by turning dark mode on and off on your computer or phone.

First, here is a Codepen for how I would have approached this before the days of CSS pre-processors:

Here's a Codepen for how I was doing this until recently, declaring multiple variables that were then only called depending on the theme chosen:

Lastly, here's how I'm approaching it now with CSS variables:

Even for this basic example, the CSS to create the dark them has reduced from 9 lines of CSS down to just 4 and I'm not having to declare variables that have nuanced names that are specific to bits CSS.

It's the way forward but problematic for older browsers. I'm not supporting them for anything I'm doing at the moment so while I'd like to find a solution, it's not a real concern for me at the moment. Next, I really need to tidy up how this is handled on my blog and on SITEJOY so that they are a little easier to manage. Not often I change things drastically, but if a new element is added to the page I shouldn’t have to think about how it works in either mode.

I feel like I was blind to what seems really obvious because o was already using variables, just in the ‘wrong’ post of the workflow!

Happy to say I’m no longer a CSS variables snob!

Discussion (5)

miguelmj profile image

I didn't want to make two modes for my own site because I only knew the SASS solution... now the CSS variables seem more viable, I might give it a try. Thanks!

cchana profile image
Charanjit Chana Author

Exactly my dilemma, you could even combine the two so CSS variables are driven by ones you’ve already defined in SASS. Overkill? Perhaps, but it also brings as much flexibility as you need there to be.

eddsaura profile image
Jose E Saura

Interesting. Can we get the same with a user interaction? With a switch?

I think I've read something about it, maybe creating a parent class with .dark in the body or something like that.

cchana profile image
Charanjit Chana Author

I wondered the same, but don’t really have an answer other than having to declare more specific variables and then creating a theme you can apply by switching classes.