Adding dark mode support
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: