Skip to content

[css-color-6] It should be possible to specify the contrast algorithm for color-contrast() #7356

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

Closed
LeaVerou opened this issue Jun 14, 2022 · 8 comments
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. css-color-6 Needs Edits

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Jun 14, 2022

Since we know that WCAG 2.1 has huge known problems and WCAG 3.0 isn't quite ready yet, we should not ship a color-contrast() that mandates use of a broken algorithm.
Instead, the algorithm should be explicitly specified with either syntax.

Since passing levels depend on the algorithm and 4.5 in WCAG 2.1 may not be the same as 4.5 in another algorithm, I'd suggest it's specified via functions, e.g. color-contrast(white vs yellow, blue to wcag2(4.5)) or color-contrast(white vs yellow, blue to wcag2(AA))

(Issue filed following breakout discussions between @svgeesus, @fantasai, @argyleink and myself)

@SebastianZ
Copy link
Contributor

Question is also what to do if the specified algorithm (or maybe even the contrast ratio) are not supported by the UA. Should it be invalid at computed value time or should the UA fall back to its default algorithm or something else?

Sebastian

@argyleink
Copy link
Contributor

works for me.
i'm only a tiny bit curious why it's a function, not really how other css functions work, but i mean it matches the mental model so thats nice.

@LeaVerou
Copy link
Member Author

Question is also what to do if the specified algorithm (or maybe even the contrast ratio) are not supported by the UA. Should it be invalid at computed value time or should the UA fall back to its default algorithm or something else?

No reason to be invalid at computed value time, it should be invalid at parse time so it can be detected by @supports

i'm only a tiny bit curious why it's a function

Because levels don't mean anything outside their algorithm, so they need to be associated with that. If levels were just keywords we could hyphenate (e.g. wcag-aa), but since they can also be <number>, a function is the only way to go.

@Myndex
Copy link
Member

Myndex commented Jun 19, 2022

HI Lea @LeaVerou

...levels don't mean anything outside their algorithm, .... (e.g. wcag-aa),..

Not only that, but: AA encompasses two discrete ratios, 3:1 and 4.5:1, and AAA encompasses three distinct ratios, those of AA, and the additional 7:1.

And the 3:1, 4.5:1, and 7:1 as calculated by WCAG 2 math are different than every other contrast math, and the actual results skew differently relative to the overall total luminances being tested as does every other contrast math or method, ever...

And I know you know this but for anyone reading along at home, among the reasons is that there is no such thing as an absolute contrast: Contrast is not real, just as color is not real, it is a context sensitive perception and about as hard to nail down as grasping a wet bar of soap in the middle of a typhoon while being chased by hungry wild geese.

@svgeesus
Copy link
Contributor

Not only that, but: AA encompasses two discrete ratios, 3:1 and 4.5:1, and AAA encompasses three distinct ratios, those of AA, and the additional 7:1.

Yes, we know; in CSS we have separate keywords for those:

The keyword AA is equivalent to 4.5, AA-large is equivalent to 3, AAA is equivalent to 7, and AAA-large is equivalent to 4.5 .

And the 3:1, 4.5:1, and 7:1 as calculated by WCAG 2 math are different than every other contrast math,

Yes, that is what "Because levels don't mean anything outside their algorithm" is saying.

@svgeesus svgeesus changed the title [css-color] It should be possible to specify the contrast algorithm for color-contrast() [css-color-6] It should be possible to specify the contrast algorithm for color-contrast() Jun 22, 2022
@LeaVerou LeaVerou moved this to Tuesday in 2022 New York Meeting Aug 1, 2022
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed specifying the contrast algo for color-contrast(), and agreed to the following:

  • RESOLVED: Allow color-contrast() to specify the algo and level, by taking an algo function as an arg
The full IRC log of that discussion <TabAtkins> Subtopic: specifying the contrast algo for color-contrast()
<TabAtkins> lea: since there are problems with every contrast algo known right now
<TabAtkins> lea: wcag2 is well known but with big problems
<TabAtkins> lea: theres' a study linked in the issue that shows it has something like 40% false results
<TabAtkins> lea: we suspect the reason in practice people don't realize how bad it is is because the colors you feed in aren't random, they're already "probably readable", so this is a second line of defense
<TabAtkins> lea: but once it's baked into a css algo it'll be used to generate color pairs without author intervention
<TabAtkins> lea: so if it's this bad, we can't use it
<TabAtkins> lea: otoh, ACAG[?] is positioned as a successor, but has issues
<TabAtkins> lea: Patent filed for it, unclear if it's usable
<TabAtkins> lea: weird note about licensing for web-based usages
<chris> qq+
<TabAtkins> lea: and the author has been rather difficult to work with, got a temp ban from w3c
<una> q+
<TabAtkins> lea: there are some other algos, chris probably knows more, they also generally don't produce great results
<chris> s/ACAG[?]/APCA
<TabAtkins> lea: So a) it should be possible to specify the algo specifically, rather than picking a default
<flackr> q+
<TabAtkins> lea: but even if we make it mandatory, that's not a solution, authors will learn an invocation and we won't bea ble to shift away
<TabAtkins> fantasai: So not shipping yet, but we stil lneed to add keywords
<TabAtkins> lea: not keywords, some kinda function since the levels are different fro each algo
<Rossen_> ack chris
<Zakim> chris, you wanted to react to lea
<TabAtkins> chris: re the patent situation
<TabAtkins> chris: At a certain maturity level you can lodge an exclusion
<TabAtkins> chris: In this case the patent was disclosed but not excluded
<TabAtkins> chris: the actual disclosure has some wording about license restrictions
<TabAtkins> chris: the patent policy does not allow such restrictions
<TabAtkins> chris: it needs RAND as well as free
<TabAtkins> chris: w3c patent people say it's unenforcable
<TabAtkins> chris: so currently it seems to be royalty-free
<Rossen_> q
<florian> q-
<TabAtkins> florian: the patent disclosure period has elapsed, and there was no exclusion
<lea> q+
<chris> q+ to talk about levels per algorithm
<TabAtkins> una: agree its 'important to speciy the algo
<Rossen_> ack una
<TabAtkins> una: Wanna be able to use new algos in the future
<lea> q-
<TabAtkins> una: Yesterday we also talked about letting the browser decide the auto algo
<dbaron> +1 to "should be able to specify the algorithm" (pending the details, which are in other issues!)
<TabAtkins> una: If wcag2 is the current default, we want the browser to be able to update to new ones
<TabAtkins> una: I think this can be done if there's no keyword (or auto?)
<TabAtkins> una: and a keyword means the user always wants a specific algo
<TabAtkins> una: seems like best of both worlds for usability and ability to be specific for contrast algo
<TabAtkins> una: tldr, should be able to specify contrast algo but also should be able to say auto
<Rossen_> ack florian
<Rossen_> ack flackr
<TabAtkins> flackr: if the user has told the browser they have a color deficiency, can the UA take that into account and select a contrasting color based on it?
<TabAtkins> chris: people with atypical color vision don't ahve reduced contrast sensitivity
<TabAtkins> chris: with exception of red-on-black
<TabAtkins> chris: where they're actually better
<Rossen_> q?
<Rossen_> ack chris
<Zakim> chris, you wanted to talk about levels per algorithm
<TabAtkins> chris: re the "function instead of keyword", it's because the different algos use different numeric ranges
<TabAtkins> dbaron: responding to una
<Rossen_> ack dbaron
<TabAtkins> dbaron: maybe pushing a little outside this issue
<TabAtkins> dbaron: i am skeptical of anything where we ship something and later change what color is produced
<TabAtkins> dbaron: people will evaluate whether they've succeeded in their design not just by writing a contrast(), but also by looking at it and making sure they like it
<florian> +1
<TabAtkins> dbaron: if we go and change the colors later, people will probably be unhappy and pages will be broken
<TabAtkins> una: this is why i think it should be an option
<florian> q+
<TabAtkins> una: but authors should generally be using a specific algo
<TabAtkins> una: but an option could be to let the browser decide, if they don't care as much about a particular combo
<TabAtkins> dbaron: i think once we ship the feature it'll be hard to change
<Rossen_> ack florian
<TabAtkins> color-contrast(unstable-algo-don't-use(1.0) ...)
<TabAtkins> florian: agree, we'll be dealing with less fuly-informed authors and teams, who will show the result to someone in approval who won't be caring about code, just result, and even if it's well-intended it might look wrong alter
<TabAtkins> florian: even if you told them it could be different that wouldn't matter
<TabAtkins> una: i'm afraid if we ship the current contrast algo people wont' update their code, adn pages will be stuck on bad results
<Rossen_> q
<bkardell_> q+
<TabAtkins> miriam: I agree that's a useful use-case and what I'd expect
<TabAtkins> miriam: I think it would be useful to recommend to authors to put the algo into a custom prop so it's easy to update later
<Rossen_> ack fantasai
<TabAtkins> fantasai: given how broken wcag2 is, we're asking a lot of people to bake wcag2 into their page, and they won't update their code ever
<TabAtkins> fantasai: if wcag2 is the only thing we have to offer and we don't have the ability to auto-upgrade it
<castastrophe> q+
<TabAtkins> fantasai: then even 5 years from now people will be teaching that you use the wcag2 algo
<chris> q+
<TabAtkins> fantasai: seems harmful to the web and we shouldn't be shipping it as a solution
<bkardell_> q-
<TabAtkins> fantasai: if we wanted to go down the auto-updating path and ship now, we could ship a more limited version that only gives white or black
<TabAtkins> fantasai: that's basic, but it solves a useful problem
<TabAtkins> fantasai: text is readable
<TabAtkins> fantasai: but for this issue, i think we do need the ability to choose an algorithm
<TabAtkins> fantasai: not just because we want authors to change what they use over time, but they also might actually want a specific algo, frmo design or legal perspective
<TabAtkins> fantasai: in the future we might have an excellent algo, but the laws in XYZ might require contrast that conforms to wcag2, I want to be able to say I want the color that conforms to awesome-algo and wcag2.
<TabAtkins> fantasai: So not just one algo, but 2+
<chris> q?
<TabAtkins> fantasai: In the case of "most contrasty one", you can only ahve one, but in "reach at least this level" we can offer multiple
<bkardell_> q+
<chris> q-
<TabAtkins> fantasai: I agree that using a function makes most sense so we can put appropriate scale info in
<TabAtkins> fantasai: so for this issue proposal is to add one or more algo functions to color-contrast() arg
<TabAtkins> fantasai: that accept the numeric level
<TabAtkins> fantasai: and this should be one of the prelude args
<TabAtkins> castastrophe: so much +1 to that
<lea> needless to say, +1 to everything fantasai just said
<TabAtkins> castastrophe: from design system perspective, people aren't likely to update this code frequently
<TabAtkins> castastrophe: so having generic name function with a default algo that we can update as we go along...
<TabAtkins> castastrophe: i don't know if we've changed defaults under the feet
<TabAtkins> castastrophe: we've done that a lot in design components, using the bad default for now until we figure it out
<TabAtkins> fantasai: i agree with that, but that's a different issue about the default
<bkardell_> q-
<Rossen_> ack castastrophe
<TabAtkins> fantasai: for the purpose of this discussion it's assumed specified
<una> q?
<una> q+
<TabAtkins> castastrophe: was thinking about generic name
<TabAtkins> fantasai: name is color-contrast(), and you'd say like color-contrast(wcag(...), black, white)
<TabAtkins> una: so this issue is about always requiring a specific color-contrast algo
<TabAtkins> fantasai: for now, we can discuss optionality later
<TabAtkins> una: def +1 on making it possible
<TabAtkins> una: i would like a world where it's not required
<fantasai> default algorithm -> https://github.com//issues/7361
<TabAtkins> una: we'll discuss that later
<Rossen_> ack una
<TabAtkins> chris: we can always relax it later if it's required now
<TabAtkins> fantasai: so proposal is we add to color-contrast() a number of specific-algo functions accepted as one of its arguments
<TabAtkins> dbaron: clarifying - saying the level is optional. does that mean if you don't you get th emost contrasty choice, and if you do you get the first color that meets the level?
<TabAtkins> chris: yes, that's already what the spec says
<TabAtkins> Rossen_: objections
<TabAtkins> lea: what's the reason to get the most contrasty pair? why not just default to a reasonable level?
<dbaron> s/if you don't/if you don't give a level/
<TabAtkins> RESOLVED: Allow color-contrast() to specify the algo and level, by taking an algo function as an arg
<TabAtkins> Rossen_: that's another issue, we'll discuss that later
<TabAtkins> una: what if none of the color values work?
<TabAtkins> chris: If you give a target and you run off the end of the lsit, you'll get either white or black, whichever is better
<dbaron> (what happens if algorithms disagree on whether white or black is higher contrast? :-P)

@yatil
Copy link

yatil commented Aug 2, 2022

Yes, we know; in CSS we have separate keywords for those:

The keyword AA is equivalent to 4.5, AA-large is equivalent to 3, AAA is equivalent to 7, and AAA-large is equivalent to 4.5 .

I would be cautious to have the AA, AA-large, AAA and AAA-large keywords as they only apply to text. For graphical elements AA requires only a 3:1 contrast.

While I think it would be neat to be able to specify the contrast by level, it might be better to – by default – assume 4.5:1, and allow users to specify a different contrast ratio if they want to. A 4.5:1 contrast ratio is sufficient or better for all cases apart from AAA (non-large), and there are not many who aspire to AAA (unfortunately).

(I think it would also be good to explore requiring the whole contrast ratio X.x:1 instead of just the number before the :1. I floated the idea of leaving off the :1 a few years ago and while details escape me, having a ratio was seen as communicating clearer that this is about how two colors behave in coordination with each other. In the end, it might be good to align with WCAG/AG WG on that matter.)

@Myndex
Copy link
Member

Myndex commented Aug 12, 2022

...A 4.5:1 contrast ratio is sufficient or better for all cases apart...

In terms of actual accessibility, 4.5:1 is grossly insufficient for a vast portion of the visual range, most especially dark colors and "dark mode". (And oddly, 4.5:1 is more than needed for some other use cases and low spatial frequency elements).

As I've mentioned elsewhere, a numerical value can be more useful. Perhaps a single default (and if it is WCAG 2 that default should arguably be 7:1) but rather that accept only a few levels, a numerical value is beneficial. In the case of the WCAG 2 algorithm, that would allow a designer to specify 10:1, which is a more ideal level for body text.

As I mentioned in this post in 7359 combining an identifier with a contrast value would allow unambiguous contrast settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. css-color-6 Needs Edits
Projects
Status: Tuesday
Development

No branches or pull requests

7 participants