~bfiedler/website

c2083cc7005592664f290b055c2acf5a55fb5b0a — Ben Fiedler 2 months ago d879930
Draft prefers-color-scheme
1 files changed, 74 insertions(+), 0 deletions(-)

A content/blog/css-prefers-color-scheme.md
A content/blog/css-prefers-color-scheme.md => content/blog/css-prefers-color-scheme.md +74 -0
@@ 0,0 1,74 @@
---
title: "CSS: prefers-color-scheme"
date: 2021-01-27T14:03:40+01:00
draft: true
tags: [web, short-and-sweet]
---

When developing tools that interface with user's in a visual sense, I believe it
is important to cater to the user's wants (and needs) as much as possible,
whilst retaining a recognizable product identity. Probably the brightest
decision in this regard is the background color: light or dark?

Specifically regarding webpages, a variety of solutions have been developed:
JavaScript triggers, cookie-based theming, user stylesheets and time-based theming. All of these solution falls short in one important aspect: they do not
cover 100% of a user's interaction with a site. The first two solutions have no
safe default - they may always show the user the "wrong" theme first, and
require active engagement to fix, which is a burden on the user. User
stylesheets do work on first visit, however one often has to deal with broken
sites, since they were not designed for theming.  Finally, time-based theming is
silly in its own right[^1].

# The solution

In 2017, the [CSS Media Queries Level 5](https://www.w3.org/TR/mediaqueries-5/)
specification was released, and it proposes the best solution to date: a media
query named `prefers-color-scheme`. It is set by your browser, and can be set to
either `light` or `dark` - more values may be supported in the future. Instead
of requiring a user to interact with _each_ site they visit, the decision is
only made once at the browser, and can be applied to every site, even on the
first visit! And it is supported by [all major desktop and mobile
browsers](https://caniuse.com/prefers-color-scheme), simply marvelous.

Using this feature is as simple as adding a media query to your styling. Using
[CSS custom properties](https://www.w3.org/TR/css-variables/) ("variables"), all
you need to do is define the appropriate colors and you're good to go.

```
@media (prefers-color-scheme: light) {
    // light styling (default, or user has no preferencce)
}

@media (prefers-color-scheme: dark) {
    // dark styling
}
```

# Trying it out

This website fully supports theme selection based `prefers-color-scheme`, try it
out! It even inverts images[^2] to perfectly match your preferred style, a
feature I'm very proud of, even if it is virtually invisible (since almost
nobody looks at both styles).

On desktop browsers you can test it using the developer tools
([Firefox](https://stackoverflow.com/a/60481298/),
[Chrome](https://stackoverflow.com/a/60481298/),
[Safari](https://webkit.org/blog/8840/dark-mode-support-in-webkit/)). On mobile,
modern smartphones (both iOS and Android) set your preferred color scheme based
on the system theme, so changing that should also change the appearance of this
site.

Sadly, many of the sites I interact with daily do not support
`prefers-color-scheme`. Especially people who rarely do frontend work (such as
myself) may not know of this feature, and I hope to raise awareness for
user-friendly theme support.

If you have a personal blog, product or company website or any other side,
consider adding support for `prefers-color-scheme` to your theme. Even though it
has no impact on the majority of people, we ultimately design our products to
be as user-friendly as possible. Right?

[^1]: Bonus question: server time or client time? One is inaccurate for large parts
  of your visitors, the other one requires JavaScript.
[^2]: when it makes sense, so photos for example are left as-is