How to Enable Dark Mode on Your Website with Pure CSS?

Andrew
Vue.js Developers
Published in
4 min readDec 29, 2019
Photo by Kaique Rocha from Pexels

Nowadays, more and more devices start to support dark mode. Therefore, we will have to create our website with dark mode support inevitably in the future. In this article, I will show you some tricks to enable dark mode on your website with just pure CSS. And also shows you a few tools and tips you can use when you’re designing a website with dark mode support.

First of all, let introduce some CSS we will use on our examples.

1. CSS custom properties (CSS variables)

We can define a custom property and then use it through var()

/* define the property */
:root {
--main-color: balck;
}
/* use the property */
p {
color: var(--main-color);
}

var() support the second parameter as a fallback.

p {
color: var(--main-color, darkgray);
}

And we can use var() inside the var().

p {
color: var(--main-color, var(--second-color));
}

2. Prefers-color-scheme

The prefers-color-scheme CSS media feature is used to detect if the user has requested the system to use a light or dark color theme.

@media (prefers-color-scheme: dark) { 
... some style for dark mode
}

@media (prefers-color-scheme: light) {
... some style for light mode
}

Unfortunately, both attributes are not supported by IE. For CSS variables, I personally love this solution by using SASS mixin. And there are some others you can find on GitHub.

Examples

Now we know how to use those CSS attributes. Let’s jump into our examples.

1. Load the system setting

The idea is pretty straightforward. Just set all the colors as custom properties. Then do the media query to switch the setting.

/* set light mode color as default value */
:root {
--bg-color: #ffffff75;
...
}
/* switch to dark mode color */
@media (prefers-color-scheme: dark) {
--bg-color: #121212;
...
}
/* apply CSS varaible through var() */
* {
background: var(--bg-color);
...
}

2. Switch with toggle-button

Because some devices aren’t supported dark mode yet. So we still have to provide the toggle button for our users to switch from light and dark mode.
Here we use the checkbox to allow us to access the checked status through CSS.

/* light mode colors */
:root {
--bg-color: #ffffff75;
...
}
/* apply dark mode colors when button is checked */
input:checked, input:checked + * {
--bg-color: #121212;
...
}
/* apply CSS varaible through var() */
* {
background: var(--bg-color);
...
}

3. Combine both of them

For better user experience, we can combine both examples above. Load the system setting as the default. Then displays the toggle-button for the user to customize.

<!-- we will need two buttons -->
<input class="dark" type="checkbox" />
<input class="light" type="checkbox" />
<article>
...
</article>
/* deafult light mode color */
:root {
--bg-color: #ffffff75;
...
}
/* hide light button if system setting is light mode */
@media (prefers-color-scheme: light) {
.light {
display: none;
}
}
/* hide dark button if system setting is dark mode and apply dark mode colors */
@media (prefers-color-scheme: dark) {
.dark {
display: none;
}
--bg-color: #121212;
...
}
/* swith to dark mode when dark button checked */
.dark:checked,
.dark:checked + * + *,
.dark:checked + * + * > h1,
.dark:checked + * + * > p {
--bg-color: #121212;
...
}
/* swith to light mode when light button checked */
.light:checked,
.light:checked + *,
.light:checked + * > h1,
.light:checked + * > p {
--bg-color: #ffffff75;
...
}
/* apply css variable */
* {
background: var(--bg-color);
...
}

Design Guideline & Tools

There are some properties come from the material design that is worth to take a look.

  • Contrast: Dark surfaces and 100% white body text have a contrast level of at least 15.8:1
  • Depth: At higher levels of elevation, components express depth by displaying lighter surface colors
  • Desaturation: Primary colors are desaturated so they pass the Web Content Accessibility Guidelines’ (WCAG) AA standard of at least 4.5:1 at all elevation levels
  • Limited color: Large surfaces use a dark surface color, with limited color accents (light, desaturated and bright, saturated colors)

Use Chrome dev-tool can help us check that.

And here is an online tool can help us generate the color with different tone— Color Shades Generator.

--

--

Andrew
Vue.js Developers

Math → MBA → PM → Consultant → FE developer → Software engineer → ?