Dark Mode in CSS

Avatar of Robin Rendle
Robin Rendle on (Updated on )

DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!

With the introduction of dark mode in macOS, Safari Technology Preview 68 has released a new feature called prefers-color-scheme which lets us detect whether the user has dark mode enabled with a media query. Safari Technology Preview 71 also has supported-color-schemes, which… well, I couldn’t exactly tell you what that does.

The media query is like this:

@media (prefers-color-scheme: dark) {

}

It may not be supported everywhere just yet, but it’s a great progressive enhancement, it’s implemented in a good/smart/standards-compliant way, so it’s safe to start using. Just like prefers-reduced-motion!

It’s not just setting dark backgrounds with light text…

Recently Mark Otto described how we can start using prefers-color-scheme today in order to create themes that dynamically adjust to the new user setting. And the neat thing about this post is that Mark sort of frames it as an accessibility issue and shows how he uses it on his own website to adjust images so that they’re not too bright for the user:

@media (prefers-color-scheme: dark) {
  img {
    opacity: .75;
    transition: opacity .5s ease-in-out;
  }
  img:hover {
    opacity: 1;
  }
}

In the code above, Mark detects whether the user has dark mode enabled with the media query and then makes the images darker so that they match a dark background.

CSS Custom Properties may be useful

This reminds me of an excellent post by Marcin Wichary where he explores a similar technique and goes one step further by adding all sorts of filters to make sure they have a much higher contrast.

html {
  --text-color-normal: #0a244d;
  --text-color-light: #8cabd9;
}

html[data-theme='dark'] {
  --text-color-normal: hsl(210, 10%, 62%);
  --text-color-light: hsl(210, 15%, 35%);
  --text-color-richer: hsl(210, 50%, 72%);
  --text-color-highlight: hsl(25, 70%, 45%);
}

It doesn’t mean you have to give up your brand

Andy Clarke also wrote up some thoughts about how to take this fancy new CSS feature and how we might apply a dark theme across our website. He describes how to pick colors so our light/dark themes are consistent in terms of branding and how we might want to use a lighter font-weight for darker backgrounds. He writes:

Designing for dark mode shouldn’t stop with choosing darker colours. You should also consider altering typography styles to maintain readability for people who use dark mode. Light text against dark backgrounds appears higher in contrast than when the same colours are used in reverse, so to make your dark mode designs easier to read you’ll need to add more white/dark space to your text.

If your fonts offer a lighter weight, using that for your dark mode design will open up the letterforms and make them appear further apart…

What was that? It sure sounded like the joyous applause of typography nerds and designers everywhere!

It’s about inclusive design

Charles Reynolds-Talbot writes about his friend Molly, who has trouble with high-contrast white backgrounds with black text:

Assuming a style switcher is the solution to this problem, it’s nothing new. It’s just something that isn’t trendy anymore. But this shouldn’t be about fashion, this is about inclusive design for all. Solving this problem for Molly will actually solve problems for other people too. A dark mode will be better for people who suffer from migraines, have a hangover or are just browsing the web in bed at night with the light off. Designing for the few, makes things better for the many.

Dark mode by default

Remember you can reverse it and go dark by default but change to a light theme if a user specifically wants it:

body {
  background-color: black;
  color: white;
}
@media screen and (prefers-color-scheme: light) {
  body {
    background-color: white;
    color: black;
  }
}