Open argyleink opened 1 year ago
related #7937
related #7553
Some miscellaneous critique:
The discussion during the last f2f concluded that it was almost certainly far too dangerous to allow an auto
algorithm, except maybe if it was restricted to only giving black/white. When people use this function, they'll almost certainly rely on it to just do something, then visually check it, then build other colors around the result; if that result can change over time it can break a page (well, cause the colors to suddenly clash, or become insufficiently contrasted, etc). (Restricting an "auto" to just produce black/white is probably okay, since it's harder to clash or contrast badly if algos change in the future.) So, if we allow for an "auto" algo it should ignore the contrast level and only use "max".
I like the use of "more" and "less" keywords to shorthand some common usages, tho they'll similarly need to be defined as using some particular contrast algo.
I also like the default behavior of creating a result by maintaining the hue of the base color; that seems pretty reasonable, and seems to give good results in general.
I think your grammar around target/algo isn't quite right. I think your intention is that you can give an algo, or a target, or both, and you only need both when specifying an explicit ratio, right? An algo by itself implies "auto" target; a target by itself implies "auto" algorithm?
The use of /
doesn't appear necessary here. It doesn't disambiguate anything, since colors, role, algo, and target are all distinct productions that can be told apart. The need for a separator was just to create a better visual distinction between the base color and the result colors. As it is, the algo/target look like they're associated with the first color in the result list, rather than being part of the overall function operation.
Wow, that ObservableHQ demo is sweet! 🤩
Not looking at the details/order of the syntax, I do see all the necessary parts are there. It reminds me of this syntax I suggested:
More syntax ideas:
contrast-color(foreground red using wcag2(AA) vs blue, white, yellow)
contrast-color(foreground red using wcag2(AA) / blue, white, yellow)
(to make it more clear that it’s not 4 comma-separated items but something measured against 3 items)
The main components are there, similar to Adam’s proposed syntax. Key difference though is that the <contrast-algorithm>
is a function that accepts the wanted <contrast-target>
as an argument.
This allows an algo to have more than 1 argument. The (unfinished) wcag3 for example also takes font weight and size into account, which could then be expressed as wcag3(75, font-size, weight)
.
This allows an algo to have more than 1 argument. The (unfinished) wcag3 for example also takes font weight and size into account, which could then be expressed as wcag3(75, font-size, weight)
engineering made it sound like they could derive that as they needed and wouldnt require authors to pass it explicitly to fulfill the algo. hopefully authors wont have to know that much about the api surface area of a contrast algorithm to use it right.
The longer this function sits, the more that folks will use cielab to estimate L differences for contrast. [See this post here where the author suggests we don't need color-contrast()
](https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl#:~:text=body%20%7B%0A%20%20background%3A%20var(%2D%2Daccent)%3B%0A%20%20/%20We%20do%20not%20need%20to%20detect%20text%20color%20with%20color%2Dcontrast()%0A%20%20%20%20%20because%20OKLCH%20has%20predicted%20contrast.%0A%20%20%20%20%20All%20backgrounds%20with%20L%E2%89%A575%25%20have%20good%20contrast%20with%20black%20text.%20/%0A%20%20color%3A%20black%3B%0A%7D). I've considered this before as well, as relative color syntax allows me to ask for a calculated L difference easily, completely bypassing all these conversations about which contrast algorithm is the best. there's a number of problems with this doing this:
All things that contrast-color()
should do for authors, like in this proposal.
BUT, this L* calc() ability is about to be in hands before contrast-color()
. Even without relative color syntax the math can be done on a per channel basis with custom properties in a cielab space: background: oklch(calc(var(--bg-l) + 50) c h)
. The sooner we can resolve on this function, the more folks we can save from attempting to bake accessibility into their colors themselves.
I've considered this before as well, as relative color syntax allows me to ask for a calculated L* difference easily, completely bypassing all these conversations about which contrast algorithm is the best.
Hi Adam @argyleink
This proposal intends to empower the prefers-contrast media query
I just came across this thread, I am here to answer any questions that might come up or to provide assistance.
As I think you are aware, user personalization is the most important thing that can be done for accessibility. If real effective user personalization can be had, then many other concerns about accessibility become very secondary or even moot.
As such I've been considering some of the needs that could potentially be addressed by appropriate media queries, such as prefers contrast or theme, etc.
One issue is that what one user needs, another user may find harmful or interferes with their needs. Visual presentation is probably one of the more complicated and common situations where this issue is present.
There are easily 10 basic themes or contrast modes, I put the supporting minutia in the spoiler.
10 different modes is far too much to ask an author to provide, what is needed is automated theme variations, such as creating a Daltonized palette.
Automated color palette development requires perceptual uniformity in whatever model is being used.
Hi @bramus + @argyleink
which could then be expressed as wcag3(75, font-size, weight)
engineering made it sound like they could derive that as they needed and wouldnt require authors to pass it explicitly to fulfill the algo.
You definitely do not need to send APCA the font size and weight.
If you have one color, you then only need a target Lc value (lightness contrast) to determine the needed second color.
If you don't have an $L^C$ value in mind, you can use font size & weight of the reference font to determine the needed $L^C$ value.
Hi @tabatkins
...almost certainly far too dangerous to allow an auto algorithm, except maybe if it was restricted to only giving black/white.
I agree that automatically selecting some algorithm is fraught with a lot of unexpected behavior. A black and white font flipper could work, but you don't need much of an algorithm for that.
You can pretty much convert to luminance and flip between black and white at $37\ Y$ I discuss this at the FancyFontFlipping repo
Hi @argyleink
the more that folks will use cielab to estimate L* differences for contrast.
Unfortunately $∆L$ is no improvement over WCAG 2.x. Both $L$ and WCAG_2 put center contrast at #777777
, and that is not the center of contrast.
I was working with $∆L*$ early in 2019, and found it provided no benefit on its own, however much of that work lead directly to developing SAPC which then developed into APCA.
The tangent is DPS contrast a.k.a. Delta Phi Star, which uses $L*$ as the starting point.
I hope this post was useful please ping me if you have questions.
Thank you for reading
Presented and discussed in https://github.com/w3c/csswg-drafts/issues/7937#issuecomment-1431788247
This proposal intends to empower the prefers-contrast media query by creating a function that implements the options of the media query, is simple to get started with, but can scale to advanced needs of authors and users. I feel, and others have provided feedback, that the current proposal is becoming unwieldy for the average developer and is lacking an automatic choice feature.
Since contrast is such a visual thing, I needed to build an interactive syntax so I could see and feel out the syntax results. I chose ObservableHQ as it allows creating transparent and inspectable logic and documentation, plus the ability to make things interactive and real time.
Interact with the syntax, read finer details about the implementation, all here: https://observablehq.com/@argyleink/contrast-color
Demo usage of the interactive proposal:
https://user-images.githubusercontent.com/1134620/197878368-1b30e1f2-b7de-496b-83b4-3692cb81cec3.mp4
Some notable things to observe in the proposal and video are:
contrast-color(#eee)
contrast-color(foreground #eee)
contrast-color(#eee)
contrast-color(#eee / apca)
prefers-contrast
media query keywords likemore
andless
and maps them to the algorithm's equivalent of contrast, but if left out of the function (auto
) the browser uses the users current contrast preference from the OScontrast-color(#eee / more wcag21)
same ascontrast-color(#eee / 7 wcag21)
max
as a keyword, simplifying the request forwhite
orblack
depending on which contrasts morecontrast-color(#eee / max)
The goal is to encourage usage of
auto
so users preferences are respected and remain dynamic. This means most usage of the function will be short and sweet.But, if experts want to, they can grab the reigns and really specify what they want like:
From presenting the previous syntax a few times to groups of devs, staying current with the current issues logged against this contrast function, and wanting the previous WG resolutions on contrast preference handling, this spec proposal attempts to sum as much of it up as it can, while being terse and approachable.
There's plenty of details to talk about, but this proposal feels closest to the desirable developer experience I acquired in feedback. It also aligns functionality more with existing contrast resolutions made by the CSSWG. I'd like to present the proposal and accept questions about details.
The Observable document has a section called Explanations and Reasoning that should help answer a few of the common questions:
Have fun! I feel like it's quite nice having something visual and playful to work with instead of just reading theoretical syntax over and over. You can go try it out, see results, and discover the syntax you'll want in your project.