Website Redesign: Re-thinking Dark Mode

One of the first enhancements I knew I wanted to make to this site when redesigning it was to add a dark mode. It’s not that difficult to do at a base level and is something that I personally enjoy at both an OS level (e.g. iOS dark display) and on other sites that support it.

But swapping colors based on user settings is only the tip of the dark mode iceberg. I’ve been re-thinking the way it’s implemented around here and thought I’d jot down a few of the things bouncing around in my head as well as some lessons I’ve learned so far.

Let’s re-visit what it means to be “dark mode”

It’s hard to imagine someone who is unfamiliar with the concept of dark mode. It’s been around for at least the last year as Android phones adopted it early in 2019, but probably gained more widespread attention when iOS introduced it later in the year and with official support for it on the web introduced in Safari 68 last October.

By “support” I’m referring to a new CSS media query that allows developers to tap into a user’s OS settings to detect whether the user prefers a light or dark display.

iOs Display & Brightness settings

That media query? It looks like this:

@media (prefers-color-scheme: dark) {
  /* Styles for users who prefer dark mode */
}

@media (prefers-color-scheme: light) {
  /* Styles for users who prefer light mode */
}

So that’s what we’re dealing with when we talk about “dark mode” on the web. We have a means of knowing how a user prefers to view content on their device and adapt our own UI accordingly. It’s not an especially difficult concept to grasp but — like many things in web design and development — there’s a lot of nuance that’s worth understanding and taking into consideration when implementing it.

What dark mode can (and probably shouldn’t do)

It’s easy to think of dark mode as a technique for swapping colors on a website. The user prefers a certain type of display on their device, so we respect that setting on our sites. Seems like a win-win, right? The user gets to control their own experience in both apps and websites, creating a consistent look and feel throughout.

But we’re probably short-changing the feature if we only look at it as a way to respect the color settings of a device. For example:

  • Does the user prefer dark UI everywhere or only in apps?
  • Is the user’s preference based on aesthetics, or making content more accessible?
  • How dark is dark? Is black always the best replacement for white, or are there other color combinations that either serve the purpose just as well or even better?
  • Is color the only part of the UI that needs to be respected? It’s easy for our minds to go straight to color when we’re working with terms like “light” and “dark” but what we’re really talking about is contrast — and that transcends color.
  • What’s the browser support for the media query? Are some users going to lose out and, if so, how do we accommodate them?

Yes, there’s a lot of nuance there and there’s probably a lot more that could go in there.

Dark mode browser support

The last point in that list is worth briefly calling out. I mean, what’s the point of designing for dark mode if, um, no one can experience it?

Well, that’s not the case. The media query is very well supported at the time of this writing. All major browsers support it (excluding Internet Explorer and a few minor mobile browsers) with 80.85% global coverage, so it’s most certainly ready for prime time — and the specification for it is still unofficial!

The future of dark mode may be impacted as the specification evolves. For example, there is another CSS property in the proposal to force a color scheme, essentially opting fully out of color preferences at the OS level and instead maintaining full control of the CSS.

My current approach to dark mode

At this very moment, I’m employing dark mode using the media query at the :root level. I’ve created a number of custom properties that combine into a palette of baseline colors I use throughout the design of this site.

:root {
  --red: #fd1e1e;
  --orange: #fd5a1e;
  --gray-lightest: #f7f2f1;
  --gray-lighter: #e8e3e1;
  --gray-light: #cabdb9;
  --gray: #b0a3a0;
  --gray-medium: #7d7472;
  --gray-dark: #615a58;
  --gray-darker: #463e3b;
  --gray-darkest: #221d1b;
  --white: #fff;
  --black: #000;
}

Then I assign those colors to other custom properties with more functional names:

<pre class="language-css"><code>:root {
  /* Same as before */
  --primary-color: var(--orange);
  --text-color: var(--gray-darkest);
  --background: var(--gray-lightest);
  --site-title: var(--gray-dark);
  --border-color: var(--gray);
  --link-border: var(--primary-color);
  --link-color: var(--text-color);
  --link-hover: var(--white);
  --link-current: var(--gray-darkest);
  --code-blocks: var(--white);
  --error-color: var(--red);
  --table-background: var(--gray-lighter);
}</code></pre>

Finally, I re-assign those colors based on the user’s preference using the media query:

@media (prefers-color-scheme: dark) {
  --text-color: var(--white);
  --background: var(--gray-darkest);
  --site-title: var(--gray);
  --border-color: var(--gray-lightest);
  --link-color: var(--white);
  --link-current: var(--white);
  --code-blocks: var(--black);
  --table-background: var(--gray-darker);
}

That’s a valid and legit approach. It’s also the cheapest, easiest way to go.

But I’d be lying if I said that’s all there is to it because now this opens up additional questions I have yet to answer:

  • Should the user be able to toggle between light and dark mode?
  • Are the contrasts of my dark mode color combinations equally or more compliant

Why can’t anything in front-end development be easy? ????

What I’ve changed since last time

This is already my second time addressing dark mode in the redesign of this website. The first time walked through my initial implementation, but didn’t really go into UX considerations… or really anything beyond scratching the surface of how I did it.

Since then, I’ve been focusing on the color palette itself. One of the questions I asked earlier is whether black and white are always perfect replacements for one another. My answer for that is a resounding no. Black text on a white background is a lot different than white text on a black background. Again, since we’re talking more about contrast than color, there are varying degrees of contrast. In other words, replacing one high contrast with another may not be the best user experience. Maybe it’s better to swap a high contrast with a medium contrast. The W3C has a nice definition of this with examples worth checking out.

So, what have a I changed? Well, my “dark” mode is now a much lower contrast than it was. After using dark mode myself on my own site for a few weeks, I determined — based on my own experience, of course — that white text on a near-black background was taxing on my eyesight. I’m far-sighted and found my eyes feeling sore after reading a couple of my own posts. I decided to “design” a softer appearance that removes blacks and grays altogether In favor of muted earth-tones and a less intense primary color.

My homepage before the change.
The UI is a lot “softer” this way.

Where to go from here

I probably need to continue refining the palette a bit, but I’m pretty comfortable with it in general. This palette is actually a lot closer to a design iteration I really liked but ended up abandoning, so I feel like I got to sneak in a second design of the site.

The new palette opened my eyes to contrast in general, so I’ll probably re-visit my “light” mode palette as well. The high contrast is pretty strong and might need to be lowered a notch to encourage more reading. This is a blog, after all.

I also want to address the whole UX consideration of letting users toggle between light and dark mode. It’s not a trivial enhancement, but it’s certainly doable with a little effort… and JavaScript.

I also want to consider more things. How about images? Should the contrast be muted there as well? Is the change from light to dark jarring? It is, so I’m glad there isn’t a way to toggle between them at the moment!

So, more to come. Just a little housekeeping since the last time I checked in.

✏️ Handwritten by Geoff Graham on March 7, 2020

12 Comments

  1. # March 8, 2020

    […] I love it when people redesign “in the open” and write about it. I’d just like to shout out to our own Geoff who has been doing this for 3 months now. He started in late December last year. He’s been sharing stuff like his dev tooling choices, considering performance, considering accessibility, that moment where you question everything, and then getting back on with it by evolving choices, like how he’s handled dark mode. […]

  2. # March 9, 2020

    […] I love it when people redesign “in the open” and write about it. I’d just like to shout out to our own Geoff who has been doing this for 3 months now. He started in late December last year. He’s been sharing stuff like his dev tooling choices, considering performance, considering accessibility, that moment where you question everything, and then getting back on with it by evolving choices, like how he’s handled dark mode. […]

  3. # March 9, 2020

    Hmm.

    While “dark mode,” to me, definitely means a darker background and lighter text, it also means shades of black and grey.

    Your “earth-tones” dark mode to me just looks like shades of brown, in fact I didn’t think it was a dark mode at all. As a colleague just said, “too much light coming out of there.”

    But I guess this is all subjective. Great article anyway!

    • Geoff Graham
      # March 9, 2020

      That’s definitely what I struggle with most when it comes to the whole “dark mode” thing: subjectivity. What is “dark” anyway, right? Is there a prescribed contrast that it has to be, or is it relative to the “light” design?

      Take Safari’s Reader Mode, for example. There’s high contrast and a sepia tone versions available, both of which are darker than the standard light version. Do both of those qualify as “dark” mode?

      I guess I’m on the side of “yes” as far as anything that is darker than the light alternative. I totally get that what’s in place now may not qualify as “dark” relative to other designs that use different color palettes, but I think it works because of how it currently sits next to the existing light version.

      That said, I may change it up yet again once I revisit the light version. Who knows? Maybe what I have as “dark” now will be come my “light” mode. ????

  4. Stephen
    # March 9, 2020

    My early explorations into making “dark mode” sites a few years back now, led me quickly to realise that actual black #000 and white #FFF are not the best tones to play with. It’s great reading your personal journey.

    • Geoff Graham
      # March 9, 2020

      I’m totally starting to see it the same way. Even working with high contrasts has been taxing my eyes lately.

  5. # March 9, 2020

    may be, i had my own perspective to dark mode i do liked the hard one. mean the old dark mode, dont know why? can you please explain more about soft ui mode i dont get it i think.

    • Geoff Graham
      # March 9, 2020

      I’m calling it “soft” but that’s not an official thing or whatever. What I mean is that the contrast between white text on a medium-brown background is much “softer” than white text on a near-black background. You can see the difference in the contrast ratio using the WCAG contrast checker. The previous high contrast version has a higher contrast ratio, whereas the new version is less intense.

      Not sure if intentionally reaching for a lower contrast is wise, but it feels right to me based on my experience using the site myself for a couple of months.

  6. # March 9, 2020

    […] One of the first enhancements I knew I wanted to make to this site when redesigning it was to add a dark mode. It’s not that difficult to do at a base level and is something that I personally enjoy at both an OS level (e.g. iOS dark … Read More […]

  7. # March 9, 2020

    Really informative. I am going to follow this as a guide for my next project that I am about to start.
    Dark mode switch in the front end is the thing that I want to include for sure. Please let me know if you have suggestions about dark mode switch.
    Thanks

  8. Bhojendra Sah Rauniyar
    # March 10, 2020

    How can we enable dark mode on chrome browser – desktop app?

  9. Bhojendra Sah Rauniyar
    # March 10, 2020

    Ah, I found it:
    Navigate to chrome://flags and search for dark.

Comments are closed.