CSS Media Queries Level 5 is coming and though it’s still heavily in progress, there is a particular new option that feels like a mistake in the making to me: prefers-contrast: forced. I’ll explain why I feel that way in this article.
I no longer understand prefers-contrast
The prefers-contrast
media query indicates whether someone prefers more or less contrast within the boundaries of your sites design. At least, that’s what I thought it meant, and it’s also how macOS seems to implement it with their ‘increase contrast’ accessibility feature. This is in contrast to the forced-colors
media query, which overwrites all your styles.
To me it was clear that they served different purposes: one was to indicate a preference for an implemented design, just with more (or less) contrast, the other wanted 100% certainty that their colors were respected. Clear difference, clear implementation.
Except that turned out to be wrong.
While macOS sees prefers-contrast
as a discrete thing, the spec (and Windows) intricately links it to forced-colors
. There, prefers-contrast:more
matches when forced-colors
with a high contrast theme is active, and prefers-contrast: custom
is active with a contrast theme that has anything other than a full black or white background.
So now I’m left wondering: What on earth do spec makers expect website builders to do with prefers-contrast
? If forced-colors
already overwrites all the colors, what contrast is there left for us to change?
prefers-contrast
is a useless media query, and I don't understand why.
This isn’t the first time I’ve voiced concerns about prefers-contrast
: earlier versions of the spec had a forced
value that would match only when forced-colors
was active. I thought this was a really dumb idea, wrote about it and to my surprise, the forced value got removed from the spec. Victory!
…Except they put it back as custom
and apparently retooled the entire media query to match with forced-colors: active
.
Worse still, the spec only mentions this in the forced-colors
section, while the prefers contrast section only mentions prefers-contrast: custom
matching when forced-colors: active
matches. Under forced colors however, this is what the latest version of the spec says:
In addition to forced-colors: active, the user agent must also match one of prefers-contrast: more or prefers-contrast: less if it can determine that the forced color palette chosen by the user has a particularly high or low contrast, and must make prefers-contrast: custom match otherwise.
Similarly, if the forced color palette chosen by the user fits within one of the color schemes described by prefers-color-scheme, the corresponding value must also match.
Contrast this to what the version before it said:
The UA will provide the color palette to authors through the CSS system color keywords and, if appropriate, trigger the appropriate value of prefers-color-scheme so that authors can adapt the page.
That's a whole new section essentially fusing prefers-contrast
to forced-colors
.
Coupling forced-colors
and prefers-contrast
like this completely breaks the ‘contract’ that the prefers-*
prefix gives: a user has preference and it’s up to you to implement it. This is in contrast to other media queries, like width
and, indeed, forced-colors
, that tell us that something is a more intrinsic state of the device being used to access your site.
Prefers-*
in media queries is no longer something you can depend upon, and CSS is a little bit less explainable and a little less consistent.
Why do this?
I have no idea why they decided this was a good idea. Maybe the spec makers are confused by the name of ‘contrast themes’ on Windows and decided that contrast is contrast and no further research was needed?
I also have no any idea what to do with prefers contrast. It exists, and there is literally no reason to use it on its own.
This is doubly annoying for macOS, which has a very clear implementation for prefers-contrast: more
. If you want to adapt your design for macOS, you can no longer use just that. You need to check if prefers-contrast: more
is active, and if forced-colors
isn’t:
@media (prefer-contrast: more) and (forced-colors: none) {
/* Only now can you apply styling for the macOS implementation */
}
No one is going to do that, and the spec makers know this because "adoption being low" is a common argument made by the CSS working group against any new media queries (like prefers-reduced-complexity
, which is also tacked onto prefers-contrast
by using it without a value). Usage being low is a great way to stop any discussion dead in the water, and is far from consistently applied throughout the specs being written.
So that leaves me with this: I no longer understand prefers-contrast
. I can’t explain why you would use it, I don’t know who it’s for or what developers are expected to do with it. Do you?