K P Bowler

Implementing Dark Mode


Implementing Dark mode

"Dark mode" means changing your app's colour scheme to a dark or more muted palette. It has been poipular among developers for a long time, but recently Apple released Dark Mode for MacOS, which brought this feature to the wider desktop. The linked article explains the benefits, but you can now add dark mode to your site.

Step 1: Creating the root element

We will be utilizing CSS variables in order to make the process as easy as possible. To start the process, you must define a :root block in your stylesheet to store all the variables. At the top of the stylesheet, add code like this:

:root {
  --background-color: #fff;
}

In the above code, we are adding a new :root selector, which represents the "root node" of the tree that represents the document. In terms of HTML, that's the <html> tag.

The next line added a CSS variable (sometimes called a "custom property"). The name must begin with two dashes --, then you can add the name of the variable, with dashes representing spaces.

Repeat the process for each colour that you wish to change when you enter dark mode, using the default "light" version of the colour. This will probably be the one that is already in the CSS.

Step 2: Adding the dark mode media query

Now that we have the colours that will change when we enter dark mode defined, we need a way of telling the browser to change them. We can use the "prefers colour scheme" media query for this. Add this code below your :root definition from earlier.

@media (prefers-color-scheme: dark) {
  // dark-specific styles go here
}

This media query allows the browser to detect if the user has set the system's display preferences to a light or dark theme, then apply the code within based on the value of the colour scheme, "light" or "dark".

Step 3: Dark mode specific overrides

Now we need to add the rules that will actually make your site look different in dark mode.

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: #000;
  }
}

As you can see, we have overridden the values defined in the original :root element to set a dark value for the --background-color variable. Repeat this process for each each of the variables set inside the original :root element.

Step 4: Start using CSS variables

CSS variables are not not supported in IE, and only supported in Edge 16+, so please ensure that you are in a position to use this technique with your user base. Refer to the Can I Use...? page for more details.

So now we have styles defined for each of your colours for light and dark mode, but how do you actually use them? We need to use CSS variables to replace each hard coded colour reference with a reference to the variable defined in your :root element. We use the CSS function var() to accomplish this.

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

This code means that the value stored in the --background-color will be applied to the <body> element as the background-color CSS property.

Now, the magic happens because we have an override set for the --background-color within our media query. If the browser detects that the system's theme changes from light to dark, the media query will kick in and override the value stored in the variable, this is due to the cascading nature of CSS, so lower lines in the file have priority.

That's all you need to implement dark mode on your site!