DEV Community

Dita Rahma P.
Dita Rahma P.

Posted on

Dark Mode with CSS Variable

Let's admit that Dark Mode now is a thing, and people love it. It does look cool, like the terminal in your computer, or your code editor. I bet you prefer them to be dark as well (people who use the light theme on their code editor is a monster lol).

Now because of the trend, let's say that we want our web to be dark too. But being a mindful dev, we also consider our users who prefer light mode over the fancy dark mode have their preference noticed.

Firstly, let's create the main container and put the light background color as the default state. Don't forget to set the margin to be 0 on the body and set the height to be 100vh so the container will have a full-screen display.

<div id="simulateDarkMode" class="container">
</div>
Enter fullscreen mode Exit fullscreen mode
:root {
  --brand-basic: #dee8f3;
}

body {
  margin: 0
}

.container {
  height: 100vh;
  background-color: var(--brand-basic);
}
Enter fullscreen mode Exit fullscreen mode

Notice that instead of assigning direct color, we use CSS variables that are placed on the root element to store the colors we're going to use, and assign it to the background-color CSS property. Here I choose the HEX #dee8f3 to be my default color scheme (it's light blue with a little hint of grey).

To make the color switchable, then we're going to put the button inside our container that acts as a switch to change the color scheme. Then, let's put the data-* attribute on the container that acts as a flag whether the page is on light mode or dark mode. Because data-* attribute is meant to store custom data private, then let's call ours data-theme. Don't forget to assign the default value to it.

<div id="simulateDarkMode" class="container" data-theme="light">
  <button id="toggleDarkMode" type="button" class="btn-toggle" onclick="toggleDarkMode()">
    DARK MODE
  </button>
</div>
Enter fullscreen mode Exit fullscreen mode

We have a flag and a button that calls a function. Now put the logic inside the function that will turn the page from light mode to dark mode.

function toggleDarkMode() { 
 const container = document.getElementById('simulateDarkMode');
  const buttonDarkMode = document.getElementById('toggleDarkMode');
  const dataTheme = container.getAttribute('data-theme');

  if(dataTheme === 'dark') {
    container.setAttribute('data-theme', 'light');
    buttonDarkMode.innerHTML = 'DARK MODE';
  } else {
    container.setAttribute('data-theme', 'dark');
    buttonDarkMode.innerHTML = 'LIGHT MODE';
  }
}
Enter fullscreen mode Exit fullscreen mode

The function is pretty basic. We have three variables; container, which is the outer wrapper we set our background-color; buttonDarkMode, the switch button itself; and dataTheme to store the value inside our custom attribute data-theme.

When the function is called, it will check the value inside the data-theme attribute. If the value returns dark, then it will change it to light and also change the button text and vice versa.

The data-theme value is successfully changed by clicking the button, now let's move back to the CSS to make the color changing happens.

:root {
  --brand-basic: #dee8f3;
}

[data-theme="dark"] {
  --brand-basic: #31456a;
}

body {
  margin: 0
}

.container {
  height: 100vh;
  background-color: var(--brand-basic);
}
Enter fullscreen mode Exit fullscreen mode

The only thing we need to add to the CSS is an exact match selector that will only select the element with the exact data-theme attribute with a value equal to dark. Inside the selector, we replace the --brand-basic value from light color to dark color. That's it! Now your page can turn from light mode to dark mode in a single click!

Here's an example in codepen if you want to check (I put some sprinkles in the CSS to make it a bit pretty and smooth)!

Discussion (5)

Collapse
pbnj profile image
Peter Benjamin (they/them)

Nice.

Additionally, one can toggle based on the users' system/OS theme using the prefers-color-scheme media queries.

Example:

/* Light mode */
@media (prefers-color-scheme: light) {
    body {
        background-color: white;
        color: black;
    }
}
Enter fullscreen mode Exit fullscreen mode
/* Dark mode */
@media (prefers-color-scheme: dark) {
    body {
        background-color: black;
        color: white;
    }
}
Enter fullscreen mode Exit fullscreen mode

For more info, see the spec: drafts.csswg.org/mediaqueries-5/#p...

Collapse
nikhilmwarrier profile image
nikhilmwarrier

Hey! That's really awesome! I will try it myself!

Collapse
andrewdaniels profile image
Andrew Daniels

@dita Does this work for React?? If not is there an easy fix to make it work in react?

Collapse
ditarahma08 profile image
Dita Rahma P. Author

This article is written using vanilla javascript and basic CSS, so I believe it works on the most framework out there including React :)