DEV Community

Cover image for Adding a dark theme to your website with css variables
Brett Anda πŸ”₯🧠 for Developer Bacon πŸ₯“πŸ₯“

Posted on • Updated on • Originally published at


Adding a dark theme to your website with css variables

So, you want to add a dark (or light) theme to your website quickly and without destroying the code that you already have. This method works by taking the color theme settings from the device that is browsing your website and send info to the browser and CSS about those color settings.

CSS Variables

All of the colors that you would like to change between light and dark mode you will have to set as CSS variables. Setting CSS variables looks like this and can be changed for different classes or in this case media queries.

body {
    --background-color: #000;
    --text-color: #fff;
Enter fullscreen mode Exit fullscreen mode

To call the variable after being set you have to follow the below code.

p {
    color: var(--text-color);
Enter fullscreen mode Exit fullscreen mode

Something that you should also add when calling CSS variables is adding a default fallback color for older browsers that can't handle CSS variables. When setting the fallback to make it for the default color scheme if the device can't handle the @media (prefers-color-scheme: dark) {} media query. Adding a fallback is as simple as the below.

p {
    color: var(--text-color, #fff);
Enter fullscreen mode Exit fullscreen mode

If you are using SCSS/SASS variables then you need to print the variable like this.

p {
    color: var(--text-color, #{$white});
Enter fullscreen mode Exit fullscreen mode

Prefers color scheme Media query

One of the newer media queries that have been added is the prefers-color-scheme media query. This checks for the color theme of the browsing device and can change styles based on that. The media query at its basics is shown below.

@media (prefers-color-scheme: dark) {
    p {
        color: red;
Enter fullscreen mode Exit fullscreen mode

The options for the media query are: dark, light, and no-preference. Side note, the light color scheme is the default if the device does not support this media query.

Top comments (4)

weeb profile image
Patrik Kiss • Edited

Why does no-one ever talk about the real difficulties of making a completely working dark mode?

It's not as simple as using some variables and media queries at all.

You can define a variable with any color, you still need to apply the that to every single element that need to change.

And you can't just do
something like p{color:white;}, 'cause what if not all p elements need to change?

In that case, you need to use lot of selectors, to reach those certain p elements that need to change color.

Or you can create a class like .change-color{color:white;}.
But in this case, you need to add this to every single element that need to change color.

And then do either with every single button, span, p, input etc element.

I've seen several articles like this, about variables and this new media query, but it's not this simple at all.

Creating a fully functioning dark mode is difficult, especially on a complex, dynamic website.

aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan

It's admittedly difficult and leads to a lot more styling than you probably need for your site.

On my dev website (shameless plug), the dark mode theme uses CSS custom properties for most things.

There are, however, certain situations where I'd rather not create a custom property. In those cases, I have a themed SCSS mixin that lets me pass in the property name, the light mode color, and the dark mode color.

Also, finding the right color combinations is a royal PITA.

brettanda profile image
Brett Anda πŸ”₯🧠 • Edited

This article doesn't talk about those difficulties because the websites that I have implemented this to have not been large websites with the need super complex CSS selectors.

(I am more used to writing with SCSS.) With the elements that need there own color change but don't need a whole new global variable, for one thing, I have added the media queries to that one element. If elements that don't need to change are one specific page I also add page classes to the body like <body class="page page-contact">

Hope this helps :)

daniel13rady profile image
Daniel Brady

@weeb That aligns 100% with the very little experience I have with styling websites πŸ‘ Would you be willing to write a post going into the intricacies in further detail? I'm very interested!

I think OP wasn't trying to show how to theme a website, but rather showcasing how CSS variables and media queries could be applied to such an endeavor.