A simple CSS trick for dark mode

Media inquiries are probably something you’re already familiar with. They’re widely used to make websites more responsive. The viewport’s dimensions are stored in the width and height attributes. Then you use CSS to render different layouts at various sizes.

In the same way, the prefers-color-scheme media query works. The user can choose between a light or dark theme for their operating system. That value is in Prefers-color-scheme. Although the W3C spec specifies that future values such as sepia may be supported, the value is either light or dark. For both modes, I specify distinct CSS variable values and leave it up to the user’s operating system to select.

The prefers-color-scheme media queries

The two variations of the prefers-color-scheme media query are:

/* Light mode */
@media (prefers-color-scheme: light) {
   :root {
       --body-bg: #FFFFFF;
       --body-color: #000000;
   }
}

/* Dark mode */ 

@media (prefers-color-scheme: dark) {
   :root {
       --body-bg: #000000;
       --body-color: #FFFFFF;
   }
}

—body-bg and —body-color are CSS variables in the above CSS. As you can see, the values for both modes are different. I’m using a white background with black lettering for the light theme. I’m using a black background with white text for the dark theme.

Since the spec says that W3C might introduce future values, it makes sense to convert this CSS into a boolean.

/* Light mode */
:root {
   --body-bg: #FFFFFF;
   --body-color: #000000;
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
   :root {
       --body-bg: #000000;
       --body-color: #FFFFFF;
   }
}

I’m defining a light theme by default in the above code, and converting it to a dark theme if the media query is dark. As a result, all future values added to the media query will default to the light theme.

Using the CSS variables

Now that I have different values for different themes, I need to actually use them to style the page.

body {
   background: var(--body-bg);
   color: var(--body-color);
}

CSS uses the var() syntax to use variables. Set the background to the value of —body-bg and the color to the value of —body-color in the above code. The values of these variables come from the media query, as you can see. That is, the color of the background and foreground changes depending on the OS settings!

This is the real power of the media query: Providing a consistent user experience from OS to the web page.

If you go to findmymastodon.com and switch your OS’s theme, you’ll see the transition from one theme to the other.

Conclusion

It’s worth noting that utilizing prefers-color-scheme is the same as using any other programming language. I create variables whose values vary according to a set of rules. After then, those variables are used in further processes.

The ability to let your website adjust to the user’s theme of choice is a great accessibility feature. And it further blurs the line between desktop and web for the benefit of the user. The latest browser versions support prefers-color-scheme, so you can begin experimenting today.

Happy coding.

Leave a Comment