I implemented an automatically-activated dark mode on A Place For My Head about a week ago. It took a couple of hours. Well, a couple of hours and a couple of years, but who’s counting?

Personally, I’m a steadfast adherent of what would logically be ‘light mode’. This is in part due to the lasting effects of certain medications I once had to take that permanently made it harder for me to read light text on dark backgrounds, and in part because dark mode has unclear benefits and potential downsides (‘night shift’ is similar). Still, I’d like to avoid creating an unpleasant experience for anyone used to darker colours.

A muddle of colours

The biggest obstacle was selecting the colour palette, since every guide to implementing dark mode warns you not to use pure black and pure white. (To be fair, my regular palette mostly avoids those too.) While I could have mimicked Eric Meyer’s amusingly clever ‘Minimal Dark Mode Styling’, mechanically inverting the colours doesn’t make for a good reading experience.

I turned to a friend who uses dark mode almost but not quite everywhere, asking him to suggest a few sites with simple dark schemes. I used these as a starting point as I searched for my primary colours. Once I had arrived at a pleasing combination of foreground and background, I experimented with link colours. I found one I quite liked, so I entered it into my colour scheme generator of choice (Adobe Color, the first thing that came to mind).

I used different modes to find parts of the scheme and shades for the varying link states. Of course, there was a loop involved: I refined the base colours in the generator as I encountered better variations, which naturally led to tweaking the entire scheme once again. In fact, I found several delightful link colours before making a decision.

I once dealt with colours on the web only as RGB hex triplets, but the HSL model is supported everywhere these days and makes it easier to derive harmonious colours. It also comes closer to how humans perceive colours, although colour models are all just that: models.

I converted both my light palette and the chosen colours from RGB to HSL via the Chrome Dev Tools and played with the individual components. I tried to maintain similarity by preserving certain components. For example, the normal link colour is hsl(190deg 100% 70%). To create a brighter underline, I keep the hue the same but reduce the saturation and increase the lightness, giving me hsl(190deg 80% 75%). On the other hand, while I initially did the same for the visited link colour, my ultimate choice is more distinct, to aid comprehension.

Some recommend reducing the weight of the text in dark mode, as light-on-dark text inherently appears heavier. The font I’m using has no light weight, but in any case, I personally don’t perceive a significant difference in this case.

I also implemented a neat trick to make the scrollbars match.

Imperfection is progress

I termed it an ‘automatically-activated’ dark mode because it’s controlled by the (prefers-color-scheme: dark) media query, which is usually tied to preferences in the browser or the operating system. Modern sites typically allow overriding this through a toggle. However, A Place For My Head is still happily JavaScript-free and I don’t see where a toggle could sensibly sit in my document structure, short of adding a persistent header element or floating icon. The only place where it wouldn’t disrupt the carefully-crafted flow of the page is in the footer, which is… unhelpful.

Perhaps I’ll find a solution before another two years pass. We shall see. For now, I trust this is an improvement over not having a dark mode at all. (I should mention, too, that I’m aware shadows and borders don’t look their best in dark mode.)