Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-color-adjust] Should forced-colors support color-mix()? #11097

Closed
cssence opened this issue Oct 28, 2024 · 12 comments
Closed

[css-color-adjust] Should forced-colors support color-mix()? #11097

cssence opened this issue Oct 28, 2024 · 12 comments
Labels

Comments

@cssence
Copy link

cssence commented Oct 28, 2024

CSS Color Adjustment Module Level 1

I realized that Firefox performs a color-mix() in Forced Colors Mode when all the colors in the mix are CSS System Colors:
https://cssence.com/2024/color-mix-in-forced-colors-mode/
https://codepen.io/cssence/pen/abeVWYK

Chromium-based browsers do not. After filing an issue (Bugzilla ticket #1927252), Mozilla responsed they implemented this on purpose, i.e. not a bug but a feature. We should clarify what the behavior should be, the Chromium-based way or the Firefox way.

@Loirooriol Loirooriol added the css-color-adjust-1 Current Work label Oct 28, 2024
@kbabbitt
Copy link
Collaborator

From the spec:

Forced colors mode is an accessibility feature intended to increase the readability of text through color contrast. Individuals with limited vision often find it more comfortable to read content when there is a particular type of contrast between foreground and background colors.

Allowing mixing, even of system colors, seems to me like it would be counter to the intent of the feature.

@nt1m
Copy link
Member

nt1m commented Nov 13, 2024

I would prefer allowing mixing of system colors (which WebKit also supports fwiw), but also allow the UA to override it with currentColor when forced colors mode is enabled.

@nt1m
Copy link
Member

nt1m commented Nov 13, 2024

It isn't the job of CSS to prevent illegible/non-ideal colors from being created fwiw. But if the colors are non-ideal for forced colors mode, then forced colors mode should be able to override them.

@kbabbitt
Copy link
Collaborator

It isn't the job of CSS to prevent illegible/non-ideal colors from being created fwiw.

This is true, but it's orthogonal to the question of allowing mixing in forced colors mode. The goal of forced colors mode is to give the user control over foreground/background color combinations. The canonical use case is high contrast, but it can be any combination - some users might find low contrast more comfortable to read, for example. Mixing these colors, however, would not be applying them as they were set by the user.

@nt1m
Copy link
Member

nt1m commented Nov 13, 2024

Yeah, my point is that forced colors mode should be able to prevent the colors from being mixed, and override the mixed colors with appropriate colors.

@svgeesus
Copy link
Contributor

if its computed value is a color other than a system color, its used value is instead forced to a system color as follows:
Properties Affected by Forced Colors Mode

I read that to mean that you can mix colors if you want but the computed value that results will be overridden by a system color.

@emilio
Copy link
Collaborator

emilio commented Nov 13, 2024

I can provide some context for this, as this is also perhaps relevant to the appearance: base discussion. The reason I implemented this in Firefox (in this bug) was so that color mixes like the ones @josepharhar and @nt1m are suggesting in #10909 (comment) can be used in forced-colors mode.

Those kinds of mixes allow authors to have meaningful hover / active feedback colors even when in forced-colors (without a designated system color for them).

@kbabbitt
Copy link
Collaborator

I read that to mean that you can mix colors if you want but the computed value that results will be overridden by a system color.

Thanks, yes, that's a detail that I missed. I just checked, and that is in fact how it works in Blink.

Those kinds of mixes allow authors to have meaningful hover / active feedback colors even when in forced-colors (without a designated system color for them).

Personally I'd be open to defining new system color keywords to cover these use cases. But I'm also wondering if using some other indicator in forced colors mode instead might (a) more closely follow the user's palette preferences, and (b) steer away from needing to invent even more system color keywords in the future as new use cases come up. Straw example just to illustrate one possibility:

@media {forced-colors: none) {
  select option:enabled:hover {
    background-color: color-mix(in lab, currentColor 20%, transparent);
  }
  select option:enabled:active {
    background-color: color-mix(in lab, currentColor 30%, transparent);
  }
}

@media {forced-colors: active) {
  select option:enabled:hover {
    outline: 1px dotted canvastext;
  }
  select option:enabled:active {
    outline: 1px solid canvastext;
  }
}

@svgeesus
Copy link
Contributor

To be clear, color-mix() of system colors is always allowed, and the input to the mix is the sRGB value of the system color. example

The issue under discussion is whether that mixed result is over-ridden in forced colors mode.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-adjust] Should forced-colors support `color-mix()`?, and agreed to the following:

  • RESOLVED: Close no change.
The full IRC log of that discussion <JakeA> I'm sad that that was timeboxed so aggressively vs the bikeshedding
<TabAtkins> ChrisL: everyone implements color-mix() with system colors. we use rgb value of those colors
<TabAtkins> ChrisL: all good
<TabAtkins> ChrisL: but what to do in forced colors mode?
<TabAtkins> ChrisL: spec say scomputed value is the mixture, used value is overriden by a system color
<TabAtkins> ChrisL: that's what chrome does. firefox lets you mix it, so you can do opacity variations/etc
<TabAtkins> ChrisL: should this be allowed?
<emilio> q+
<astearns> ack bramus
<kbabbitt> q+
<TabAtkins> emilio: i implemented firefox behavior. i think it's reasonable, it was a specific request from othe rengineers on firefox desktop
<TabAtkins> emilio: i have more concerns about relative colors, which have the same kind of issue
<TabAtkins> emilio: but i think as long as the arguments are system colors or transparent, it's reasonable to allow
<TabAtkins> emilio: but i don't care too strongly
<astearns> ack emilio
<astearns> ack kbabbitt
<TabAtkins> kbabbitt: as i commented in the issue, the goal of forced colors is to give the user control over the contrast settings that they're seeing
<TabAtkins> kbabbitt: so i think mixing them and reflecting that valu eint he computed result is fine, but what actually gets presented to the user should be reflective of their chosen palette, which precludes mixed colors
<lea> q+
<ChrisL> s/valu eint he/value in the
<TabAtkins> kbabbitt: for UI concerns, i have a brief example in the issue, there's other ways to reflect the states that someone might use mixed or partially transparent styles for. using different outline styles, for example. i've seen this in high-contrast UIs to work around it being limited
<TabAtkins> emilio: that puts a lot of burden on authors, tho.
<TabAtkins> emilio: a lot easier to say, like, "my buttons have system colors on fg and bg, and hover states are variations of that"
<TabAtkins> emilio: a lof of generic CSS I've seen uses currentcolor and transparent
<TabAtkins> emilio: don't see the point of allowing currentcolor and not system colors
<TabAtkins> emilio: if you don't allow it, you put the burden on authors to change the whole stylesheet, rathe rthan things just working
<TabAtkins> q+
<astearns> ack lea
<TabAtkins> lea: what exactly is the proposed behavior if we don't allow it? invalid at parse time? how are authors supposed to deal, use MQs?
<TabAtkins> lea: i was wondering, instead of disallowing certain things, can we just allow anything and cast the result to the closet allowed color at used value time?
<kbabbitt> q+
<TabAtkins> lea: that seems better for DX, unsure if feasible
<TabAtkins> ChrisL: that's pretty much what the spec says, that you pick the closest allowed color
<TabAtkins> ChrisL: closest not being parituclarly well defined
<TabAtkins> lea: then i'm missing something, why wouldn't we allow color-mix()?
<TabAtkins> ChrisL: we do allow color-mix(), the question is what to do with the result
<TabAtkins> ChrisL: use the computed vlaue, or one of the forced values
<TabAtkins> lea: i'd expect it to produce the result, then see which allowed color it's closest to
<TabAtkins> emilio: in firefox there's no partiuclarly well-defined notion of what's "closest"
<TabAtkins> emilio: firefox actually give syout he mixed color and you can use it
<TabAtkins> lea: i'd be surprised if the spec doesn't ahve a well-defined notion of closet
<ChrisL> " the UA determines the appropriate forced system color—​which should match the color that would result from an empty author style sheet whenever all of the element’s affected properties are likewise UA-determined."
<TabAtkins> florian: regardless of that, i think the spec and chrome do snap the result to the closest color; the question is whether we do chrome or firefox behavior
<ChrisL> ie handwaving
<TabAtkins> emilio: i think chrome probably treats it something closer to revert
<TabAtkins> florian: you mean chrome doesn't pick the closest color, it just chooses something?
<lea> oof. We should *at least* provide a way to determine closest, even if non-normative
<TabAtkins> emilio: I'd be surprised, yes. i think it's more like if you use any ohter non-allowed color
<TabAtkins> kbabbitt: I expect what emilio said is correct. Blink sees the color-mix(), sees it's not a system color, and substitutes
<astearns> ack TabAtkins
<ChrisL> q?
<fantasai> TabAtkins: With regards to emilio's point about being able to do generic stylesheets that slightly change colors, part of the deal is, that subtle distiction would be invisible to users of forced colors mode anyway
<fantasai> TabAtkins: those authors are using identical colors in such a state anyway
<emilio> q+
<fantasai> TabAtkins: Those authors should be doing something different in forced colors mode regardless
<astearns> ack kbabbitt
<TabAtkins> kbabbitt: +1 to what Tab just said
<fantasai> kbabbitt: +1 to what Tab said
<astearns> ack emilio
<TabAtkins> kbabbitt: also prirority of constituences, should lean to user preference for what they're seeing than author convenience
<TabAtkins> emilio: i see two kinds of forced color users. ones that need a specific color palette, and ones that just want one.
<TabAtkins> emilio: depending on which user, the color-mix() works great for the latter
<florian> q?
<florian> q+
<kbabbitt> q+ to respond on the "need" vs "want" use cases
<lea> I'm still very confused. E.g. what is the result of `color: color-mix(in lab, allowedColor1 0%, allowedColor2);`? It should not be different than `color: color-mix(in lab, allowedColor1, allowedColor2 100%);` or `color: allowedColor2`
<TabAtkins> emilio: I agree you need to do something with more contrast for the former case, but allowing color-mix() doesn't preclude that. It does make life easier for the second class.
<astearns> ack florian
<TabAtkins> astearns: I think user needs should override user wants
<TabAtkins> florian: the primary intent of this feature is a11y, not theming
<TabAtkins> florian: it *might* be used by people who like certain colors, but the primary intent is for people who need those colors
<stepheckles> q+
<TabAtkins> florian: if it happens to work for the theme enjoyers, great, but we're not designing toward them
<lea> q?
<TabAtkins> emilio: but Tab's point is, for those users it might not make a difference etierh way
<fantasai> TabAtkins: not necessarily. If it's subtle, might not be distinguishable
<ChrisL> tab++
<fantasai> TabAtkins: if not subtle, could defeat the contrast goals of the user
<astearns> ack kbabbitt
<Zakim> kbabbitt, you wanted to respond on the "need" vs "want" use cases
<fantasai> TabAtkins: if using their chosen colors, then good for them
<TabAtkins> kbabbitt: on need vs want, another feature is preferred color schemes, a better fit for users who just *want* dark mode or a particular set of colors but can tolerate mixes
<astearns> ack stepheckles
<TabAtkins> kbabbitt: but as others have said, forced colors is primarily about users who *need* that level of contrast
<TabAtkins> stepheckles: i've seen articles recently with folks becoming aware of color-scheme property, and discovering system colors as a part.
<TabAtkins> stepheckles: trying to get the ability to produce light/dark agnostic themes, before we have better support for light-dark()
<TabAtkins> stepheckles: also, the example in the GH issue didn't even use the forced-colors MQ
<ChrisL> Q+ to answer
<TabAtkins> stepheckles: so want to clarify - does color-mix() using system colors autoamtically get overriden because it's not a system color?
<TabAtkins> stepheckles: I think if authors have a specific reason to need a specific color to work, like color swatches for products, they still have the ability to use forced-color-adjust
<astearns> ack ChrisL
<Zakim> ChrisL, you wanted to answer
<TabAtkins> ChrisL: slightly confused about what was asking
<TabAtkins> ChrisL: system colors work the same way as normal colors
<TabAtkins> ChrisL: but specifcially *when* we're in forced colors mode, there's this overriding
<TabAtkins> stepheckles: the first examples in the issue just describe some examples without forced-colors MQ in use, so it's a little confusing
<TabAtkins> ChrisL: I linked to a codepen, when we're not in forced colors it seems like all browsers are happy to use system colors, mix them, etc
<TabAtkins> astearns: so i think i'm hearing we should resolve on no change to the spec, and consider firefox's forced-colors behavior to be a bug
<TabAtkins> astearns: emilio, do you want to go back to the people with this request and ahve a convo?
<TabAtkins> emilio: i could. I think this isn't the right decision, but I don't want to object.
<TabAtkins> emilio: if you have a disabled button, being able to make semi-transparent button text...
<TabAtkins> emilio: we don't ahve a great set of system colors to reflect the relevant state. this gives you the escape hatch to modify system colors for that
<TabAtkins> emilio: I think in the ideal world we'd have systme colors for all the states authors care about
<ChrisL> q+ to say some reasonable examples work, but allowing it also allows many unreasonable examples too
<TabAtkins> (making the text low contrast for disabled buttons is, very specifically, the behavior we want to avoid for forced-colors users, fwiw)
<astearns> ack ChrisL
<Zakim> ChrisL, you wanted to say some reasonable examples work, but allowing it also allows many unreasonable examples too
<TabAtkins> ChrisL: we've seen some good example of only changing opacity, probably benign. but if we allow color-mix to be used in general, people can do all kinds of wacky stuff, people can defeat th epoint of the mode. so i'm comfortable with it being overridden.
<TabAtkins> emilio: but authors could just use forced-color-adjust:none, right?
<TabAtkins> astearns: counter is thats' the authors specifically *choosing* to override forced colors mode. Allowing color-mix() to work allows them to screw up colors by accident.
<TabAtkins> emilio: i think overall they could do more good than harm, but i'm not objectin.
<TabAtkins> astearns: anyone else who'd object to resolving this no change?
<TabAtkins> RESOLVED: Close no change.
<TabAtkins> emilio: I guess by extension we should disallow relative colors?
<TabAtkins> ChrisL: yes, i'll open a separate issue due to time

@svgeesus
Copy link
Contributor

There is no change to the normative text, but I think an example showing this would be helpful for authors and perhaps implementers. Hence Needs Example or Figure

@tabatkins
Copy link
Member

I said this in the IRC chat, but just wanted to emphasize that the case Emilio brought up to argue for allowing mixing (making a button's text partially transparent to indicate a disabled state) is precisely the behavior we need to be worried about, because it lowers the contrast of the text against the background and potentially renders it hard to read for users who need high contrast in the first place.

So allowing this falls into the "might actually harm the users in question". If the author isn't specifically writing (forced-colors)-aware styles, it's probably better for at least some users to have the disabledness simply not be visible (because the text is forced back into ButtonText) but the button still be readable, versus it being low-contrast and difficult to read.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants