Adding dark mode support
2 min read

Adding dark mode support

How I added dark mode support to my custom-built website.
Adding dark mode support
Photo by Terry Vlisidis / Unsplash

Update: June 11th, 2022

This is an article I posted on my previous website, before I moved my blog over to Ghost. I thought I'd leave it in here in case anyone is looking to add dark-mode support to their custom-built websites.

I’ve recently fallen into the trap of reading news sites when I wake up. Since it's often still dark, reading a page with a white background is pretty brutal on my eyes. When I started updating this website I wanted to add in support for dark mode so that anyone reading my blogs or articles that I write here won’t have tears streaming down their face while reading it in the dark.

This website is a custom-built create-react-app and uses tachyons for CSS. After a bit of research, it ended up being surprisingly simple to add dark mode support. The basic requirement was using CSS variables and the light/dark mode media query.

First off leveraging the power of css variables we create all colours as variables:

:root {
  --background-color: #ffff;
  --background-color-secondary: #ffff;
  --border-color: #eee;

  --text: #000;

  --text-primary: #000;
  --text-secondary: #000;
  --text-header: #e7e7e8;
  --text-link: #38b2ac;
}

Following that we need to create some classes that use these colours. I created a few to support the text, background and borders:

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

.bg-secondary {
  background-color: var(--background-color-secondary);
}

.text-link {
  color: var(--text-link);
}

.border-colour {
  border-color: var(--border-color);
}

.text-primary {
  color: var(--text-primary);
}

At this point, I needed to make some changes to my actual React components. Tachyon has predefined colours that you can use for setting the border or text colour of components. I had to find all those class definitions in my React components and replace them with the above-defined class's.

Finally the magic media query that glues everything together. We create a prefers-color-scheme for dark mode and define different colours for all our css variables:

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: #161625;
    --background-color-secondary: #2d2d40;
    --border-color: #15151e;

    --text: #fff;

    --text-primary: #fff;
    --text-secondary: #b1b1b2;
    --text-secondary: #e7e7e8;
    --text-link: #38b2ac;
  }
}

Now if a user switches to dark mode, the website will automatically adjust. If you are on a Mac, you can go to Settings -> General and click on Dark Mode. This page will automatically change. Magic!!!

I found the following these three websites helpful while researching this: