#583: Review Request for CSS Color Adjust Level 1

Visit on Github.

Opened Dec 7, 2020

HIQaH! QaH! TAG!

I'm requesting a TAG review of CSS Color Adjust Level 1. This module introduces a model and controls over automatic color adjustment by the user agent to handle user preferences, such as "Dark Mode", contrast adjustment, or specific desired color schemes.

Further details:

  • [your link here still goes to the github.io URL y'know] I have reviewed the TAG's API Design Principles
  • Relevant time constraints or deadlines: none, other than the usual "increasing web-compat pressure against changes to shipped features as time goes on"
  • The group where the work on this specification is currently being done: CSSWG
  • The group where standardization of this work is intended to be done (if current group is a community group or other incubation venue): CSSWG
  • Major unresolved issues with or opposition to this specification: fingerprinting issue (see also all open issues)
  • This work is being funded by: spec-editing by Google, implementation work by Microsoft, Google, Apple, Mozilla

You should also know that... we're not thrilled with the very generic name of the color-adjust property, but at this point it's been shipping for too long to change. :(

We'd prefer the TAG provide feedback as (please delete all but the desired option):

🐛 open issues in our GitHub repo for each point of feedback

Discussions

Discussed Dec 7, 2020 (See Github)

Elika: This one might warrant a full TAG review. It was also drafted more recently, and only has 3 major features, so much easier to pull out the relevant points.

... grid would be a much taller order to explain, for example.

Comment by @tabatkins Dec 7, 2020 (See Github)

Explainers

This specification introduces three new features related to controlling how/when colors are auto-adjusted in certain ways:

  • the color-scheme property, which controls whether or not browser-provided parts of the page's UI respect the user's chosen color scheme
  • the definition of Forced Colors Mode, and the forced-color-adjust property which controls whether or not FCM is allowed to apply to a given element
  • the color-adjust property, which controls whether the browser is allowed to automatically adjust colors to the user's assumed preferences in different media, such as suppressing background colors when printing to save ink

The color-scheme property is part of the larger cross-spec definition of Color Scheme support, aka “Dark Mode”. The WebKit team posted a reasonable explainer about the overall feature in https://webkit.org/blog/8840/dark-mode-support-in-webkit/. OSes now widely implement the ability to capture and reflect a user's preference for “light” vs “dark” UI, and this information is presented to a web page via the (prefers-color-scheme) media query, allowing a page to choose different colors and images to honor the user's preference. Some parts of the page are styled and rendered by the browser, however, such as form controls and scroll bars, and thus can't be directly restyled by the page author. The 'color-scheme' property negotiates between the uses’s preferred color schemes vs. author-supported / preferred color schemes.

This is necessary to expose as a control, rather than just part of the default behavior of the browser, because the vast majority of pages on the web were authored before color scheme support existed, and thus are generally authored with colors chosen to work well with the (reasonably consistent) set of "default" input/scrollbar/etc colors. Changing this unilaterally on pages has a small but serious chance of rendering these widgets difficult to see or use due to the colors the page is already using. A more common but less destructive issue is that making scrollbars and form controls dark, but keeping the rest of the page in the author-specified colors (usually very light) wouldn't actually achieve anything useful for most pages, and would end up just making pages look awkwardly composed for no benefit to the user.


"Forced Colors Mode" is a special accessibility mode exposed by some OSes, most notably Microsoft Windows via its High Contrast Mode feature. This can be thought of as a stronger version of a preferred color scheme: rather than simply preferring a lighter or darker UI, the user is requesting that the OS use only a chosen set of colors. Usually this is used to force a "high contrast" UI (thus the name of the windows feature) for people with impaired vision, but it can be used for a number of other color needs, such as forcing a low contrast color scheme (which helps with some sensory processing issues). Microsoft provided a great explainer for this feature in https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Accessibility/HighContrast/explainer.md.

This color scheme is forced on a webpage regardless of whether it was authored with the expectation of its colors being adjusted. https://drafts.csswg.org/css-color-adjust/#forced-colors-properties defines precisely which properties are affected, and how. The short explanation is that the system color keywords are set to the user's chosen colors, and any property using a color other than those keywords is instead forced into one of the keywords.

This can be a fairly destructive process; most pages will still be usable, but it can occasionally cause problems, for which several mitigations are described. The first, whose definition in CSS is deferred to the next level of this spec, is a "backplate" for text, which ensures that text displayed over background images will still be readable. The second is that authors can directly use the system color keywords to style their pages, either unreservedly or gated behind the (prefers-contrast: forced) media query, and have those color choices respected, even if they're different than what the given properties would normally be forced to. The third is the forced-color-adjust property, which allows authors to turn off the Forced Colors feature for an element when absolutely necessary (when the chosen colors are meaningful and required for the page to make sense, for example, for color swatches).


Similar to Forced Colors Mode, user agents sometimes automatically adjust a page's colors to match the user's assumed preference in certain circumstances. For example, use of near-black text over a near-white background is common on the web, but ruinous when printing - printing pure black text is often cheaper and sharper than colored text that is nearly black, and large tracts of background color are expensive to print and sometimes destructive to the paper itself (particular with inkjets). Browsers commonly default to using heuristics to tell when it would be okay to just ignore the author's chosen colors and instead print as black-on-white, which is better for the user. They sometimes provide UI to the user to let them opt into printing exactly what's on the screen, but it's often buried deep in the print UI if it's exposed at all.

These heuristics can sometimes misfire, resulting in unreadable text/background combinations. Also, backgrounds and other colors are sometimes very useful to the user even when printing: for example, Google Maps "zebra stripes" the steps of its navigation directions to make it easier to read, alternating between a white and light gray background. The color-adjust property allows a page to specify that this sort of automatic adjustment should not be performed, and instead the exact colors specified by the author should be preserved. https://wiki.csswg.org/ideas/print-backgrounds lays out our decision history for the design of this functionality (which later carried over to the forced-color-adjust property, which is virtually identical).

Comment by @alisonmaher Dec 10, 2020 (See Github)

As a quick note on time constraints, we are planning to ship the Forced Colors Mode feature in full form in Chromium soon. Given this, we'd appreciate a review of Forced Colors Mode in particular if possible.

Discussed Jan 1, 2021 (See Github)

Alice: Took a look earlier and didn't see any comments since my last feedback. Noticed that they want issues in their repo, so I'll go ahead and transfer the issues there and wait for a response.

Comment by @alisonmaher Jan 6, 2021 (See Github)

I wanted to follow-up in this thread with a clarification since there was some confusion raised around what is included in the review for Forced Colors Mode, specifically around the various media queries.

The main two properties that we were planning on shipping initially are forced-color-adjust and the forced-colors media query.

The prefers-contrast media query currently does include a forced value that would match in Forced Colors Mode, but we weren't planning to ship with this media query initially given that there are open discussions around the syntax and whether the forced value should be included. Our plan was to ship this separately once the open issue has been resolved.

There was consensus, however, that we would be keeping the forced-colors media query as a part of the spec regardless of what happens with prefers-contrast: forced, which is why it's included in our initial feature scope.

Discussed Jan 11, 2021 (See Github)

Rossen: I'm deeply involved in this spec... need to recuse from reviewing but I can provide context.

... looking at the call here and basically everyone on the call is close to this issue one way or another.

Alice: ...

Rossen: color-scheme... light or dark currently, few different ways authored content can fall into a color scheme. Might come directly from OS setting, has a global application of color scheme, forced or opt-in comes down to OS implementation.

... Windows supports both forced color scheme from a11y settings, colour reduced down to a few system colours, improving readability and cognitive load.

... other one is preferred scheme such as dark and light, which are deliberately undefined; dark may be dark blue, dark brown ...

... looked at color scheme property, convinced ourselves that dark and light are the only color schemes we really need to support to accommodate modern OSes and browsers.

Alice: already a MQ for dark mode, right?

Rossen: that will evaluate whenever color-scheme is dark.

Alice: What does the property add on top of the MQ?

Rossen: Can be in dark mode, but then force colours that are light... force-colors MQ will be true, color-scheme light... dark mode will go away.

Lea: Are the use cases more like I don't want dark mode on this part of the document, or more like I do want light mode... more opt in or opt out?

... Examples in the spec say you should list out all the idents... not future-proof. If a new color scheme is listed, it's assumed I want to opt out of it.

Alice: Examples in spec also use the exact same code snippet for two different scenarios, and it's not clear what is consuming the property.

... color-adjust...

Lea: There is an open issue (#2) about whether these properties should be merged... color-adjust basically mainly applies to printing... seems like an overly generic name for a specific thing. What about making it a shorthand, of perhaps color-adjust-forced and color-adjust-economy?

Peter: May want these things to cascade differently... forced-color-adjust more likely to apply to specific elements.

Rossen: color-adjust is a legacy property for printers, has existed for many years. Ideally wouldn't be generic at this point. forced-color-adjust is quite a different use case, applies to an element and its subtree.

... since color-adjust was already there, we decided to reuse and combine it (with forced-color-adjust.

Peter: historically browsers would not print backgrounds; color-adjust allows you to opt in to printing backgrounds (for example).

Rossen: drifted away from color-scheme topic.

Alice: I'm going to leave a comment on that one.

Lea: does forced-color-adjust and color-adjust have the same basic use case (albeit in different context)? Could they be something like color-preserve?

Rossen: Opt in vs. opt out behaviour... opt-out is forced-color-adjust, you can opt out of the forcing

Alice: you revert to the non-forced colors...

Lea: it's an opt-out in both cases?

Rossen: color-adjust is an opt in (exact value)

Peter: use color-adjust when you have a background on something that really needs to be printed. e.g. you're printing a list of driving directions and need zebra striping.

... forced-color-adjust, the browser is flipping the color of the scrollbars

Lea: significant intersection in the use cases, e.g. color swatches you would want to both display and print them.

Alice: seems like color-adjust and forced-color-adjust have the same effects?

Peter: economy mode is going to suppress backgrounds. forced-color-adjust affects default colors.

... If we were going to combine, UA stylesheet would need to specify the default behaviour in each context.

Comment by @alice Jan 12, 2021 (See Github)

We discussed this in a breakout today.

The forced-colors media query and forced-color-adjust certainly seem like good solutions to a real problems (respectively, how to know when colors are being overridden because of a user preference, and how to opt out of that in rare cases when necessary).

We noted that there is an issue in the spec about merging color-adjust and forced-color-adjust. It's not clear to me why forced-color-adjust: none couldn't be used in any case where color-adjust: exact might be used. In either case, you are opting out of colors being adjusted, and in fact it might well be necessary to apply both in cases like the swatches example, or even the zebra stripes example, and using media queries to select for specific media such as print where you want colors to be overridden in one medium but not another.

color-schemes was also a bit confusing going only on the spec; having re-read Tab's comment above I now understand it better. In particular, the code examples don't really clarify much, since they're identical. It would also be helpful to have some examples which demonstrate the failure case which occurs when this property isn't available.

One thing that I note is that "normal" is more or less synonymous with "light", in practice. Why have two values which mean roughly the same thing? Could "normal" be replaced with "light" as the default?

Comment by @alice Jan 27, 2021 (See Github)

Accidentally closed, somehow.

Discussed Feb 15, 2021 (See Github)

Lea: there haven't been any updates since discussion with Alice. Alice opened a bunch of issues in CSS wg repo which are still open. Most have not received comments. No responses in the TAG issue.

Lea: adding labels to issue to indicated pending external feedback

[bumped 3 weeks]

Discussed Mar 8, 2021 (See Github)

Pending feedback, bumped.

Discussed Mar 22, 2021 (See Github)

Still pending feedback from the CSSWG

Discussed May 1, 2021 (See Github)

Lea: this is a very confusing name

hadley: agreed

Tess: especially when the main issue is "should my background image print?"

[discussion on Alice's question: One thing that I note is that "normal" is more or less synonymous with "light", in practice. Why have two values which mean roughly the same thing? Could "normal" be replaced with "light" as the default?]

Tess: It seems the WG looked at it and decided that on some devices (like TVs), normal is actually dark rather than light.

They have considered all of Alice's feedback, have come to conclusions on all of it. I'm satisfied that they've considered it all. Not sure if Alice would agree. But I'm inclined to say okay.

Agreed: we'll propose closing it

Draft closing comment:

Hi @fantasai, @TabAtkins!

Hadley, Lea, and I took another look at this during a breakout this week. Overall we're happy with this set of features that solve a number of real problems. @alice raised a number of points, and we see that the WG has considered each of them.

Thanks for bringing this to us!

Comment by @hober May 12, 2021 (See Github)

Hi @fantasai, @TabAtkins!

Hadley, Lea, and I took another look at this during a breakout this week. Overall we're happy with this set of features that solve a number of real problems. @alice raised a number of points, and we see that the WG has considered each of them.

Thanks for bringing this to us!