Dark Mode with CSS Variable
Tags: webdev, javascript, css, design
Published: 2020-11-12 12:24:40

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.


```html
<div id="simulateDarkMode" class="container">
</div>
```

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

body {
  margin: 0
}

.container {
  height: 100vh;
  background-color: var(--brand-basic);
}
```

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. 

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

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.

```javascript
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';
  }
}
```

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.

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

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

body {
  margin: 0
}

.container {
  height: 100vh;
  background-color: var(--brand-basic);
}
```

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)!

{% codepen https://codepen.io/ditarahma08/pen/ExPOgOm %}