If your browser is set to prefer dark color schemes you almost certainly noticed that our site looks a bit different over the past couple weeks. What was once a sea of blues and bright whites is now a sea of blues and dark greys.
By default the site will automatically enable the dark mode if your browser requests it. Otherwise, you can enable it anytime by clicking the icon in this site’s header.
If you are already in dark mode, you can switch to light mode by clicking the icon in this site’s header.
How We Added Dark Mode
There are many ways to support a dark mode on your website. If you browse around the internet you’ll see that a good percentage of websites support a dark theme and each one implements support in a little different way. The way a site adds support ultimately comes down to the opinion of the developer(s) doing the implementation.
Here is how we did things on our website.
CSS Custom Properties
A common practice to keep a site’s colors consistent is to use CSS Custom Properties. The cool thing about CSS properties is they may be changed based on CSS selectors.
We already had a set of CSS properties for the colors of our site which looks like this.
Notice how we use
--c-
as the prefix. That is a trick to namespace a CSS property while abbreviating to reduce the finished CSS file size. You may have seen these before as--color-
which works well, but adds an extra 4 characters for each use. If a site reuses a property say 200 times, using--c-
instead of--color-
saves 800 characters in the finished styles.
It was important to us that we did not lose the general style of our site so we left our original CSS properties intact without modifying them when dark mode is enabled.
This was a consideration unique to our implementation because the majority of dark modes on the web remove all colors in favor of just black, grey and white.
To provide CSS properties which could be manipulated depending on the mode, we added a new set of properties while changing the -c-
prefix to -d-
. We set the default values to match our original CSS properties.
Also notice the color-scheme: light;
near the bottom. This tells the browser that by default the scrollbars and other supported elements should display in light mode.
Now that we have the -d-
properties in place, we can change any properties used in the CSS throughout the site from the -c-
prefix to -d-
prefix for any colors we want to change when dark mode is enabled. Most commonly we changed background and text colors.
Great, now we have everything in place and the site looks exactly the same as it did before any changes were made. It is time to introduce the dark mode color changes.
Using a CSS class selector we modify all of the -d-
CSS properties when the main <html>
element on the page has a CSS class of dark
. This must be added to the stylesheet below the initial declaration of the original -d-
properties.
Notice we also updated the color-scheme
to “dark” to tell browsers to render scrollbars and other supported elements in a dark theme.
Toggling the Dark Mode
Now that we’ve got our CSS in place, we need a way to enable the dark
CSS class on the <html>
element when the dark mode is active.
We created some simple JavaScript which has the following responsibility:
- Check if the theme has been set in the browser’s local storage.
- Check if the browser prefers a dark theme.
- If the browser prefers a dark theme or the theme has been set to dark, add the
dark
class to<html>
. - Listen for any clicks to the mode icon in the header.
- If the mode icon in the header is clicked.
- Toggle the
dark
class in the<html>
element. - Store the user’s theme choice in the browser’s local storage.
- Toggle the
Notice the setting of
const
near the top of native JS calls. This is a trick to allow WebPack to reduce the size of the finished bundle by using a local constant. Without the constant, every call is added to bundle longhand instead of a single character variable.LocalStorage.getItem
vsa.getItem
. Not a huge savings for this small file, but it demonstrates how a large file may be reduced.
Slowly Rolling Things Out
Supporting a dark mode was a large change which affected a substantial amount of areas on the website. We’re talking 8 years of iterations to our site’s theme which needed to still function when dark mode is enabled.
We completed work on the first version of dark mode at the beginning of 2024. Instead of automatically enabling it for dark browsers, we left it off by default while providing the icon to manually opt into dark mode. The thinking here was if a user opts in to dark mode they will know how to turn it off if they run into a section of the site which is not displaying perfectly.
We used the few months of opt in to give us a chance to resolve any feedback and fine tune any areas of the site.
A couple of weeks ago we officially enabled the automatic dark mode.