Adding automatic dark mode to a website

CSS variables have become mainstream, but I was too busy with CSS-in-JS solutions for React that I hadn’t previously had an opportunity to learn the details or implement them in any environments.

As I reset this site I took this opportunity to explore the options available to make use of CSS variables and some of the newer media queries added to browsers in recent years.

CSS Variables

To start with, CSS variables are a new way to define properties in CSS. They start with a double-dash, such as --example, and can be assigned to a CSS property using the notation var(--example).

So to define a variable for particular colour, then apply this colour throughout the rest of the CSS rules can be achieved with.

body {
--brand-color: #1196cf;

h1 {
color: var(--brand-color)

CSS Variable Scope

CSS variables also bring scoping. A variable can be defined at any level of the document, such as body in the example above, and will be available to all context below it. Variables which are intended to have global scope, available to the entire document, the :root scope should be used.

The scoping of a variable also applies to definitions and overloading, so a variable may have one value in the global scope and another value in a local scope.

Prefers Color Scheme: Dark

The prefers-color-scheme media query has been added to modern browsers to indicate to a website whether the user has defined a preference for either light or dark color schemes.

This would allow a website to tailor the experience to the user by displaying light text on a dark background by overriding the color and background colours for the page, such as in this example:

body { color: black; background: white }

@media (prefers-color-scheme: dark) {
body { color: white; background: black }

Combining Prefers Color Scheme and CSS Variables

Combining these two new techniques would allow a website’s theme to be quickly configured for light and dark modes, setting variables to be used for each of the different component colours — or even any CSS property.

Once these variables have been defined, they can be used throughout the rest of the site to set the properties of the elements being rendered on the page.

This example below defines several variables that that are used in the theme of this site, setting variables --foreground, --background and several others for a light mode theme, which are then overridden with a new set of colour values corresponding to a dark mode theme. Also in this example, the dark mode theme would only be applied for screen, so they would not be used in a print context.

:root {
--foreground: #3c363d;
--background: #f4eff5;
--background2: #e5dfe6;
--code-background: #0e050e;
--link: blue;
--visited: purple;

@media screen and (prefers-color-scheme: dark) {
:root {
--foreground: #ddd4df;
--background: #160d16;
--background2: #241824;
--link: #8989ff;
--visited: #e934e9;

Once these variables had been defined, they are used throughout the rest of the site’s stylesheet.

body {
line-height: 1.5rem;
color: var(--foreground);
background: var(--background);
background: linear-gradient(var(--background), var(--background2));
a {
color: var(--link);
a:visited {
color: var(--visited);
code {
background: var(--background2);

Originally published at




He/him. Interested in how things work; breaking things and fixing things. Hobbies include cooking, coffee, coding, music, and learning to surf.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

JavaScript Arrow Functions

Building Eco Archive, a chemical safety app, with Expo

FINAL Alien Cannibal

Dark Mode Switch Without JavaScript

CSS dark mode.

Story of “…read more” with react-native

How React Works- A beginner’s guide If you have worked with React then you probably know that React…

The Little Things

People want to send messages: Building the expression web app, a summary

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Philip Boardman

Philip Boardman

He/him. Interested in how things work; breaking things and fixing things. Hobbies include cooking, coffee, coding, music, and learning to surf.

More from Medium

system-ui and friends

How I created the front end for a coin flip game that allows two people to play against each other

Select Best Font for your Website, 4 Types of Fonts Explained

Serif Fonts, Sans- serif fonts, Script Fonts, Display Fonts

Accessibility Tips, Tricks, and Resources for Web Devs

This image shows a wheelchair user at a computer.