How to tell browsers that your site supports color-schemes
Tags: html, css, webdev
Published: 2020-09-13 14:14:03

---
title: How to tell browsers that your site supports color-schemes
published: true
description: A detailed look at the color-scheme property that allows developers to define which color chemes are defined in a website
tags: html, css, webdev
canonical_url: https://www.stefanjudis.com/today-i-learned/how-to-tell-browsers-that-your-site-supports-color-schemes/
---

User preferences and settings play an essential role in how websites look in 2020. To name two examples: well-made websites look great on different devices and handle various font-size settings with ease.

Over the past few years, a new user preference made it into the group of things "that change how a website looks" – yes, I'm talking about color themes. "How to implement dark mode on a website?" was one of the most important topics in 2019. 

But how can you enable dark mode then? With today's web technology, your site can react to your visitors' color preferences (coming from the operating system) using [the `prefers-color-scheme` media query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme). This media query allows you to write CSS depending on the preferred color scheme.

```css
--color-one: #ff0000;
--color-two: #00ff00;

@media (prefers-color-scheme: dark) {
  /* redefine dark mode colors here */
  --color-one: #00ffff;
  --color-two: #ff00ff;
}
```

Technically, this approach is straight forward, but implementing a high-quality theme handling is not trivial. It includes way more than just switching some colors. To learn more, I recommend reading [Thomas Steiner's](https://twitter.com/tomayac) excellent guide on this topic: ["prefers-color-scheme: Hello darkness, my old friend"](https://web.dev/prefers-color-scheme/).

## Don't forget to indicate your site's supported color schemes

Having the ability to style websites depending on user color settings is excellent, but unfortunately, it's not covering the whole picture. So what's missing? 

Even after writing hundreds of custom CSS lines, there are usually elements still relying on browser default styling. It could be a text input field, a checkbox, a radio button, or even the good old scroll bar using the CSS rules in the browser's user agent stylesheet. __The browser doesn't know about your color scheme and comes with default styles based on a light mode.__ These styles define dark text and highlights on a bright background.

To complete your color scheme and make all your elements dark mode compatible, you have to define and overwrite all these CSS rules from the user agent stylesheet. This process is not ideal!

The [`color-scheme` property](https://drafts.csswg.org/css-color-adjust/#propdef-color-scheme) helps here. It allows you to give browsers the information on your website's supported color schemes.

`color-scheme` accepts two values:

- `normal` – your site/an element does not support color schemes
- `[ light | dark | <custom-ident> ]+` – your site or a specific element can be rendered with the defined color schemes (`custom-ident` is currently unsupported and is only defined for possible future use cases)

You can set these values as an HTML meta element or as a CSS declaration.

```html
<!-- Hey Browser, 
     this website support `dark` and `light`
     but the author prefers `dark` representation -->
<meta name="color-scheme" content="dark light">
```

```css
:root {
  /* Hey Browser, 
     this website support `dark` and `light`
     but the author prefers `dark` representation */
  color-scheme: dark light;
}
```

With this information, browsers can improve their default styling to match defined color schemes. With adjusted user agent styles, you don't have to overwrite every color to make an element dark mode compatible because the browser took care of it already.

[The spec defines the following behavior](https://drafts.csswg.org/css-color-adjust/#preferred) when a `color-scheme` property is defined:

> If the author has indicated that the page can support this color scheme, the user agent must match the following to the user’s preferred color scheme: 
> - the color of the canvas surface
> - the default colors of scrollbars and other interaction UI
> - the default colors of form controls and other "specially-rendered" elements 
> - the default colors of other browser-provided UI, such as "spellcheck" underlines
 
For the example of dark mode, this paragraph means: __if a site claims to support a dark color scheme, the browser must provide dark mode compatible colors, form controls, scroll bars and other UI elements.__

This browser behavior makes it easier to build color-schemed UIs because default UI elements adjust their color automatically. You can avoid overwriting every color! 🎉

## Browser support of `color-scheme`

If you [go to caniuse.com to check the browser support of `color-scheme`](https://caniuse.com/mdn-html_elements_meta_name_color-scheme), you'll be surprised. It looks reasonably good and it seems that only Firefox is missing to support `color-scheme`.

![caniuse.com support table showing that color-scheme is mainly supported only with Firefox missing](//images.ctfassets.net/f20lfrunubsq/6d0UJcg8d5ONEZMmJgfL31/9730c548d76ab7c11a75470b1d36ad16/Screenshot_2020-09-13_at_13.05.36.png)

Unfortunately, this support table is not telling the whole truth. According to the specification "real support" for `color-scheme` consists of two things:

1. the browser must technically support the `color-scheme` property
2. the browser must adjust colors and provide UI elements taking `color-scheme` into consideration

While Chromium browsers technically support `color-scheme`, they fail on delivering UI elements that are `color-scheme: dark`-compatible. 

Thomas Steiner put together [a useful page](https://color-scheme-demo.glitch.me/) if you want to have a look. The page toggles the `color-scheme` property every few seconds going from `light` to `dark` and back. This approach allows us to have a look at which elements react to different color schemes.

![Chrome UI elements not responding to color-scheme: dark](//images.ctfassets.net/f20lfrunubsq/5k4hoL8mr6IhqvHppox7xh/e1f0421a910f195bff1e742571eb65ab/Screenshot_2020-09-13_at_13.25.33.png)

As you see above, Chrome and Edge 85 are changing the background and text color, but UI elements like inputs and buttons stay the same.

![UI elements in Safari that are adjusting to color-scheme: dark](//images.ctfassets.net/f20lfrunubsq/4Iouaxc8SBottKsSKvoXsQ/2455d2dfbc99247c83e6597a017c6331/Screenshot_2020-09-13_at_14.09.58.png)

On the other hand, if you look at Safari, you'll see that inputs and buttons change their appearance and seamlessly integrate into a dark color scheme. That's pretty nice!

## Should you use the `color-scheme` property today?

With Chromium browsers not adjusting their UI elements to a defined color scheme, I don't think that it's prime time for the `color-scheme` property yet. If you can't rely on elements to "just fit into your dark mode theme" you still have to write all this additional CSS to make UI elements fit in.

Nevertheless, I think that this web platform addition is precious, and maybe we reach complete cross-browser support quickly. 🤞 For my site, I'll add `<meta name="color-scheme" content="normal">` to my site until I finally support dark mode. 🙈

### Additional resources

- [Spec for the `color-scheme` property](https://drafts.csswg.org/css-color-adjust/#propdef-color-scheme)
- ["Improved dark mode default styling with the color-scheme CSS property and the corresponding meta tag"](https://web.dev/color-scheme/)
- ["Don’t Forget the color-scheme Property"](https://blog.jim-nielsen.com/2020/color-scheme-property/)