Insight #4 - Don't model dark mode with a boolean
Tags: javascript, html, css
Published: 2020-06-18 08:33:01

Dark mode is trending these days. Almost all developers have it on their static Jamstack blog.

Yet, there's a common misconception that `dark mode` is only `true` / `false`. I think it's a mistake to model dark mode with a boolean, and to actually speak about `dark mode`, as if it was more important than other possible `modes`.

---

**Edit**: I may not communicate my ideas well enough in this post. It is not only about CSS media queries, but modeling color scheme modes in general.

The context leading me to write this post, is this [Docusaurus issue](https://github.com/facebook/docusaurus/pull/2939), a widely used open-source project, for which switching the public configuration API from `darkMode: true` to `colorMode: "dark"` would lead to a breaking change for thousands of users, so it's better to get it right the first time.

I do agree that it's not a big deal if you use a boolean model for your blog or website ;)

I found some parts of the `prefers-color-scheme` interesting, so I just wanted to share my findings with you.

---

Let's look at the [spec](https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme) for the CSS `prefers-color-scheme` media feature, and highlight a few parts.

## More values than `light` or `dark`

Currently, the values are `light` or `dark`. 

`no-preference` was a possible value, but browser vendors seem to all fallback to `light`.

> The values for this feature might be expanded in the future (to express a more active preference for light color schemes or preferences for other types of color schemes like "sepia").

So, new values are likely to be introduced. Maybe in the future, color-blind people will be able to ask you to display content with a color scheme that is convenient for their condition. Don't you want to support them?

A boolean is not a good way to model more than 2 possible values.


## Dangerous media queries


```css
@media (prefers-color-scheme: dark) {
  .mySelector { backgroundColor: "black" }
}

@media (prefers-color-scheme: light) {
  .mySelector { backgroundColor: "grey" }
}
``` 

You might think this media query is safe, but it's likely to break your site's theme for some users, given enough time. 

If the `sepia` value is added and used, your site won't have any of the 2 specified background colors.

> As such, the most future-friendly way to use this media feature is by negation such as (prefers-color-scheme: dark) and (not (prefers-color-scheme: dark)), which ensures that new values fall into at least one of the styling blocks.

In practice, this should not happen very frequently, because you will likely read `prefers-color-scheme` at app startup time, and handle the theme with JS and CSS variables.

## User preference

Another common misconception is that the user preference is only a system preference, but it is not.

> The method by which the user expresses their preference can vary. It might be a system-wide setting exposed by the Operating System, or a setting controlled by the User-Agent.

> Note: User preferences can also vary by medium. For example, a user may prefer dark themes on a glowing screen, but light themes when printing.

--- 

# Conclusion

For now, your blog might only support a `dark` and `light` mode and it is fine, but will this still be the case in the future, as new color modes get added?

I'd like developers to ask themselves a few more questions:

- Should your next blog post be named `How to add dark mode to your website`? It might for marketing reasons :)

- Should your open-source Jamstack plugin be called `dark mode plugin`?

- Should dark mode configuration be boolean-based instead of a union type like `"dark" | "light"`?


---

Part of my Insights series (personal attempt to write short posts more regularly).
Follow me on [Twitter](https://twitter.com/sebastienlorber), [Dev](https://dev.to/sebastienlorber), or check my [website](http://sebastienlorber.com/)