Re: [csswg-drafts] `contrast-color()` MVP should support explicit light/dark colors rather than unspecified "very light/dark colors" (#11534)

The CSS Working Group just discussed `` `contrast-color()` MVP should support explicit light/dark colors rather than unspecified "very light/dark colors"``, and agreed to the following:

* ``RESOLVED: drop `max`, do white/black by default and allow extension points later``

<details><summary>The full IRC log of that discussion</summary>
&lt;kbabbitt> lea: a while back we resolved to adopt an MVP for contrast-color<br>
&lt;hober> q+<br>
&lt;kbabbitt> ...that returned very light and very dark color, up to UA what they would be<br>
&lt;kbabbitt> ... and max version that returned white and black<br>
&lt;kbabbitt> .. after working with designers more, I've seen they don't want arbtirary dark or light color<br>
&lt;kbabbitt> ... they want specific tokens<br>
&lt;kbabbitt> ... use this dark text color, not some arbitrary decided by browser coor<br>
&lt;kbabbitt> ... in theory they could use max, get white and black, and transform it<br>
&lt;kbabbitt> ... but it seems like an easy win if you could specify your light and dark versions<br>
&lt;kbabbitt> ... ideally start with just providing dark one<br>
&lt;kbabbitt> ... usually white is OK as text color but black isn't<br>
&lt;kbabbitt> ... if you provide colors you can end up in situations with insufficient contrast<br>
&lt;kbabbitt> ... but you can do that already<br>
&lt;kbabbitt> ... so that doesn't make things worse<br>
&lt;kbabbitt> ... it's in Safari but not implemented widely<br>
&lt;kbabbitt> ... I would suggest a syntax that takes args for light and dark color, drop max, and if you don't provide args you get max behavior<br>
&lt;kbabbitt> ... 1 arg is dark color with white as light color<br>
&lt;kbabbitt> ... 2 args use those<br>
&lt;kbabbitt> ... maybe UA can figure out which is which<br>
&lt;kbabbitt> ... or we can be ordered<br>
&lt;kbabbitt> ... pretty small syntax extension<br>
&lt;kbabbitt> hober: really interesting problem, we had ? to talk through it internally<br>
&lt;kbabbitt> ... it's intersting because it turns out contrast-color is something lots of people want<br>
&lt;kbabbitt> ... for different reasons with different constraints<br>
&lt;kbabbitt> ... after we whiteboarded it, we felt best way would be separate CSS functions for different use cases<br>
&lt;kbabbitt> ... filed a new issue to suggest that<br>
&lt;kbabbitt> ... space of desired behaviors &amp; why we think they should be separate functions<br>
&lt;kbabbitt> ... 2 proposals we kicked around<br>
&lt;kbabbitt> ... one is maintainer of small/medium website who realizes that previous designer didn't use sufficient contrast<br>
&lt;astearns> https://github.com/w3c/csswg-drafts/issues/11619<br>
&lt;kbabbitt> ... trying to bring website into modern world but don't have time to redesign it<br>
&lt;kbabbitt> ... make smallest change they can that gives sufficient contrast<br>
&lt;kbabbitt> ... other is designer at a company with well thought out brainding identity<br>
&lt;kbabbitt> ...who really needs colors from a specific set<br>
&lt;kbabbitt> ... use cases all over the place<br>
&lt;kbabbitt> ... given this color, compute a contrasting color<br>
&lt;kbabbitt> ... but ambiguous because color could be used for foreground, background, borders, etc.<br>
&lt;kbabbitt> ... that's teh case we want contrast-color for<br>
&lt;kbabbitt> .. other case, given a starting color and set of colors<br>
&lt;kbabbitt> ... get the color from the set that contrasts most<br>
&lt;kbabbitt> ... guaranteed color you get out is one of the ones you put in<br>
&lt;kbabbitt> ... this also has variations because you might have different thresholds for borders etc<br>
&lt;kbabbitt> ... then there's a case where you have a pair of colors for fg and bg<br>
&lt;lea> q?<br>
&lt;lea> q+<br>
&lt;kbabbitt> ... ask engine, make minimum tweaks to these<br>
&lt;kbabbitt> ... one other that james craig though tof, put text on bg image<br>
&lt;kbabbitt> ... who knows colors of bg image, but you want a color that contrasts sufficiently<br>
&lt;TabAtkins> lea's proposal is more limited than "here's a list, pick the best" - instead you first determine whether white or black would be better, then let authors supply a replacement for white/balck<br>
&lt;kbabbitt> ... all of these are interesting and probably need different functions<br>
&lt;kbabbitt> ... disinclined to make color-contrast more complicated to do all these things<br>
&lt;TabAtkins> q+<br>
&lt;kbabbitt> ... but do want to do all of these things<br>
&lt;kbabbitt> ... using separate functions<br>
&lt;astearns> ack lea<br>
&lt;hober> https://github.com/w3c/csswg-drafts/issues/11619<br>
&lt;astearns> ack hober<br>
&lt;kbabbitt> lea: when we resolved to do contrast-color it was because there was all this complex design space &amp; use cases<br>
&lt;kbabbitt> ... no good algorithm we could use right now<br>
&lt;kbabbitt> ... [gives examples]<br>
&lt;kbabbitt> ... so we resolved to leave it up to UA<br>
&lt;kbabbitt> ... address most common case which is light + dark color<br>
&lt;argyle> 17 use cases outline in my proposal from a couple years ago https://observablehq.com/@argyleink/contrast-color, sharing here to be added to the considerations<br>
&lt;kbabbitt> ... these use cases exist but a lot of this is going back to debates where we got gridlock because it was such a big problem we couldn't move forwards<br>
&lt;kbabbitt> ....we resolved to have this version because it addresses 80% of use cases without complexity<br>
&lt;kbabbitt> ... looking to keep that<br>
&lt;kbabbitt> ... maybe we'll solve others with same fn, maybe with different fns<br>
&lt;kbabbitt> ... it's a matter of syntax<br>
&lt;kbabbitt> ... poit of this proposal is to solve common case<br>
&lt;florian> q+<br>
&lt;kbabbitt> ... don't think others are something we need to solve right now<br>
&lt;kbabbitt> ... proposing a simple tweak over what we have right now<br>
&lt;kbabbitt> ... supplying optional replacements for white &amp; black<br>
&lt;argyle> q+<br>
&lt;kbabbitt> ... it's not responsible for maintaining contrast ratios for you<br>
&lt;kbabbitt> ... if previous proposal could be implemented easily this could be too<br>
&lt;kbabbitt> ... hober's points are valid but lots of design work involved<br>
&lt;astearns> ack TabAtkins<br>
&lt;kbabbitt> TabAtkins: agree with lea<br>
&lt;kbabbitt> ... trying to avoid reopening big design discussions<br>
&lt;kbabbitt> ... this is a minimal edit to what WG decided on<br>
&lt;kbabbitt> ... to address lea's concerns without opening new problesm<br>
&lt;kbabbitt> ... I think we should accept this change, bikeshed syntax later<br>
&lt;astearns> ack florian<br>
&lt;kbabbitt> florian: worried this is a footgun<br>
&lt;kbabbitt> ... yes if the color you get is actual black or white<br>
&lt;kbabbitt> ... even if contrast function isn't perfect it will be good enough<br>
&lt;lea> q?<br>
&lt;kbabbitt> ...but here you allow user to supply something else<br>
&lt;lea> q+<br>
&lt;kbabbitt> ... sometimes they'll be surprised what's picked because contrast won't be good<br>
&lt;kbabbitt> ... sometimes what we have makes bad decisions but you know it's black or white<br>
&lt;hober> qq+ to riff on florian's footgun<br>
&lt;kbabbitt> ... if you're almost entirely black maybe not but depending on how far off you are, sometimes it will give you the wrong one between the two<br>
&lt;astearns> ack hober<br>
&lt;Zakim> hober, you wanted to react to florian to riff on florian's footgun<br>
&lt;kbabbitt> hober: thats exactly my worry<br>
&lt;kbabbitt> ... if we had a separate fn that solved, given set of colors give me one that contrasts<br>
&lt;kbabbitt> ... that would be a simple change of syntax that would address that<br>
&lt;TabAtkins> q+ to respond to tess<br>
&lt;kbabbitt> ... while it's still a footgun, if you always have one color and it returns that regardless of contrast<br>
&lt;kbabbitt> ... that's less of one because you're providing a set of colors<br>
&lt;kbabbitt> ... this is areduced version of that where you're only providing 1 or 2<br>
&lt;kbabbitt> ... this is a guess because all we have to go on is intuition<br>
&lt;florian> q?<br>
&lt;kbabbitt> ... but I think authors are less likely to screw up in that case<br>
&lt;kbabbitt> ... this isn't as good as a separte function but think we should try to solve the problem<br>
&lt;astearns> ack argyle<br>
&lt;kbabbitt> argyle: lea mentioned... I don't know any designers okay with partial color choice that didn't come from their palette<br>
&lt;kbabbitt> ... most people I've talked to is the opposite<br>
&lt;kbabbitt> ... they open palette and lcick around the pool<br>
&lt;kbabbitt> ... if you have a set and want to pick from it, good feature, but not all designers explicitly want it<br>
&lt;kbabbitt> ... we leave tasks up to browser a lot, sometimes it's not the right answer<br>
&lt;kbabbitt> .... contrast prefs of user should be taken into account<br>
&lt;kbabbitt> ... in high contrast mode this fn should return something relevant<br>
&lt;kbabbitt> ... I've tried all algos, we should punt on forcing one<br>
&lt;kbabbitt> ... we shouldn't be waiting for better algo<br>
&lt;kbabbitt> ... enhancing what we have is good, white black or from a list<br>
&lt;florian> q+<br>
&lt;kbabbitt> .... bad contrast is one of biggest a11y problems on web<br>
&lt;astearns> ack lea<br>
&lt;kbabbitt> lea: agree with argyle on taking HC into account<br>
&lt;kbabbitt> ... re: footgun - I think people are comparing to ideal fn which we don't know how tyo build<br>
&lt;weinig> q+<br>
&lt;kbabbitt> ... but without this, designers are specifying these manually<br>
&lt;astearns> zakim, close queue<br>
&lt;Zakim> ok, astearns, the speaker queue is closed<br>
&lt;kbabbitt> ... we can be absolved of responsibility, they picked it<br>
&lt;kbabbitt> ... re: having UA pick, there's not enough info in a tint to give you other tints of that color<br>
&lt;kbabbitt> ... varying lightness is not sufficient in any color space<br>
&lt;kbabbitt> ... even oklch<br>
&lt;kbabbitt> ... still have to vary chroma to get tints<br>
&lt;kbabbitt> ... if starting from a light color you can't derive darker variants<br>
&lt;kbabbitt> ...without having accent color<br>
&lt;kbabbitt> ...missing information<br>
&lt;nicole> q+<br>
&lt;kbabbitt> ...I don't think UA can come up with a good color<br>
&lt;kbabbitt> ...not a terrible result to get black &amp; white if nothing provided<br>
&lt;kbabbitt> ... I think for the people picking madly around a color picker, they can deal with black &amp; white<br>
&lt;kbabbitt> ... I don't think UA generating dark color would help them very much<br>
&lt;astearns> ack TabAtkins<br>
&lt;Zakim> TabAtkins, you wanted to respond to tess<br>
&lt;fantasai> scribe+<br>
&lt;fantasai> TabAtkins: Responding to Tess, the big thing that blocked us last time was the idea of having a function that could pick from a list of colors *because* we know our current contrast algo sucks<br>
&lt;kbabbitt> TabAtkins: our existing algo sucked and we didn't have a good replacement<br>
&lt;kbabbitt> ... that's why we subsetted down to 2 color case<br>
&lt;kbabbitt> ... white and black can go a little wrong but hard to go very wrong<br>
&lt;kbabbitt> ... going back on that will reopen every problem we had before deadlock was resolved<br>
&lt;kbabbitt> ...it is possible to footgun by supplying dark color instead of black<br>
&lt;kbabbitt> ... don't do that, we'll tell them not to do it in spec<br>
&lt;argyle> just sharing this again, as this lets you see returned colors from any contrast algo, from a list, or max white/black OR it can discover a color. all of these options we're sharing here are in this demo, and you can see how totally decent the results are https://observablehq.com/@argyleink/contrast-color<br>
&lt;kbabbitt> ... can supply own colors, they should be very dark very light<br>
&lt;kbabbitt> ... still gets us to a defensible spot even if we're stuck with ? as contrast algo<br>
&lt;kbabbitt> s/?/WCAG2/<br>
&lt;astearns> ack florian<br>
&lt;kbabbitt> florian: building on TabAtkins and lea were saying<br>
&lt;kbabbitt> ...thinkinh of it as a footgun compared to doing it manually<br>
&lt;kbabbitt> ... problem case is a light on dark theme where dark isn't very dark<br>
&lt;kbabbitt> ... and you ask for contrast between middle color and give me black or white<br>
&lt;kbabbitt> ... and get kind of gray<br>
&lt;kbabbitt> ... to contrast on kind of gray<br>
&lt;kbabbitt> ... and this fn which is supposed to give you good contrast, doesn't<br>
&lt;kbabbitt> ... on one hand, don't do this, on the other hand this is the fn that ghives me contrasty<br>
&lt;kbabbitt> ... so the only thing I can put in there is gray<br>
&lt;kbabbitt> lea: isn't that a problem with current version?<br>
&lt;kbabbitt> florian: no because it returns black<br>
&lt;kbabbitt> ... it won't return middle gray<br>
&lt;kbabbitt> ... if you can't use black, you won't use function<br>
&lt;kbabbitt> ... you won't supply it middle gray, you won't use it at all<br>
&lt;astearns> ack weinig<br>
&lt;fantasai> +1<br>
&lt;kbabbitt> weinig: second time I've impled this function, shipped it behind a flag<br>
&lt;TabAtkins> as lea pointed out earlier, you can *turn* white/black into chosen colors via RCS, fwiw<br>
&lt;fantasai> that's more explicit though. The author won't think they're getting an actual contrast computation<br>
&lt;kbabbitt> ... how do we get to the point where this is good enough and get user feedbacl?<br>
&lt;kbabbitt> ... can we resolve on this version and try it out, see feedback<br>
&lt;lea> If we can't reach consensus on this, I wonder if we can just drop `max` (and do white/black by default) so that we can extend the function later with something like this<br>
&lt;fantasai> +1 lea<br>
&lt;kbabbitt> ... seems unnecessary to keep iterating if it's contentious<br>
&lt;kbabbitt> astearns: not hearing consensus for any particular resolution<br>
&lt;kbabbitt> ... let's take back to issue<br>
&lt;kbabbitt> ... we may decide to extend as lea suggests<br>
&lt;kbabbitt> ...  might need different version<br>
&lt;miriam> +1<br>
&lt;lea> (fwiw I think that's a better design *anyway*)<br>
&lt;TabAtkins> i'm fine with that<br>
&lt;kbabbitt> Proposed: drop `max`, do white/black by default and allow extension points later<br>
&lt;kizu> +1<br>
&lt;fantasai> +1<br>
&lt;lea> 🎉<br>
&lt;kbabbitt> RESOLVED: drop `max`, do white/black by default and allow extension points later<br>
&lt;argyle> +1 that's how my proposal works in that observable<br>
</details>


-- 
GitHub Notification of comment by css-meeting-bot
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/11534#issuecomment-2625667244 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 30 January 2025 21:48:18 UTC