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-typed-om] Color conversion and contrast ratio #989

Open
atanassov opened this issue May 14, 2020 · 10 comments
Open

[css-typed-om] Color conversion and contrast ratio #989

atanassov opened this issue May 14, 2020 · 10 comments
Assignees

Comments

@atanassov
Copy link

With the the current color space additions to [css-color-4], namely lch() and lab(), we solved the declarative side of the problem. What we lack is the ability to request or at least easily convert computed color values into these color spaces. Can we allow that in Typed OM?

Further, it would be great to have a function that enables contrast ratio calc given any two colors. The expectations for color contrast described by WCAG are rather detailed and lack developer ergonomics. Typed OM seems really well positioned to help.

@LeaVerou
Copy link
Member

  1. Please note that with the relative color syntax described in [css-color-5], converting between color spaces is as simple as e.g. lch(from var(--mycolor)), which can also be computed easily via even the old CSSOM.
  2. Color contrast described by WCAG is fairly simple to compute in CSS, if we add XYZ support to color() as a predefined color space. Relative luminance is just the Y component of XYZ, and contrast ratio is just a ratio of relative luminances + 0.05.
  3. Please note that while the WCAG contrast ratio has even made it into government regulations, there is a lot of valid criticism against it, as it produces a lot of false positives and false negatives. This is a great —albeit long— thread about that.

That said, it would be good to have a color-space agnostic Color object that supports all the manipulations CSS Color does, though not sure Typed OM is a good place for it. In fact, @svgeesus and I are prototyping such a Color object and plan to release it as a library soonish. It has given us a lot of insight into API decisions for something like this, and I suspect releasing it into the wild will give us a lot more.

@mathiasbynens
Copy link

Excited to hear you're prototyping something! Eventually having a standardized Color constructor living on CSS.Color seems like a natural fit here, IMHO.

I know Lea and Chris are already well aware of this, but for those reading along, this came up earlier in this whatwg/html issue. There might be some useful suggestions in the comments.

@Myndex
Copy link
Member

Myndex commented Jun 16, 2020

@LeaVerou @atanassov Hi Lea and Rossen,

Just FYI the contrast methodology is changing in a future version WCAG (3.0 aka Silver) the current code for the new version is very beta, and will have additional capabilities for modeling and predicting contrast perception.

  • The following links assume the browser is set to the default normal font size (i.e. in Chrome, font size "Medium (recommended)") and zoom at 100%.

There is a test/example page of the algorithim here: https://www.myndex.com/SAPC/

A description of the methodology is here: https://www.myndex.com/WEB/WCAG_CE17polarity

A description of how FONT WEIGHT & SIZE directly affects contrast separate from the foreground and background colors. This is important to the understanding of perceived contrast and readability: https://www.myndex.com/WEB/WCAG_CE14weight

And my repository of some work in progress is here: https://github.com/Myndex/SAPC

NOTE: This is all beta, including explanatory texts, and subject to change. The research code name is SAPC-7, but as released will be called APCA (Advanced Perceptual Contrast Algorithm).

Please let me know if you have any questions.

Andy

@LeaVerou
Copy link
Member

Hi Andy,

Thank you for the update. It's great to hear that there are plans to improve the contrast algorithm, as it is indeed rather problematic. I tried following the thread I linked to above but it was way too long and seemed to be mostly notes of original research. Is there a working group resolution or draft spec? I'm afraid until there is, we cannot build on top of it in other specs, but we will certainly keep this in mind in anything we design.

@Myndex
Copy link
Member

Myndex commented Jun 17, 2020

I tried following the thread I linked to above but it was way too long and seemed to be mostly notes of original research. Is there a working group resolution or draft spec? I'm afraid until there is, we cannot build on top of it in other specs, but we will certainly keep this in mind in anything we design.

@LeaVerou Hi Lea,

Yes, thread 695 get quite dense. The first three links in my post above provide a working example, and some documentation on the methodology.

The official working draft is not released for Silver, but there is a work in progress you can view here:

EDIT: to replace an obsolete link with this catalog of APCA resources.

But yes, this is more of a "heads up/what's coming." and to be clear the aim is to predict readability as opposed to perceived contrast. Complete models like Hunt or ICAM are very complex; here the goal is to keep the prediction as simple as possible to maintain readability as opposed to a complete prediction of image assessment.

Something much farther off is the SAPC standard observer and SLAB or SLUV, a lab type space but specific to sRGB. (More focused on accessibility adjustments)

Let me know if you have any questions or thoughts.

@svgeesus
Copy link
Contributor

Note that Color 4 does include sample code for color conversions and, while this is non-normative and illustrative, it does work. I used it to make a lot of the diagrams and examples for CSS Color 4 and 5.

It isn't necessarily a good API design, it was primarily intended to be super simple to read and understand.

To avoid cluttering the sample code, I put additional stuff that I needed in practice into a separate utilities file which includes, for instance, the WCAG 2.x relative contrast ratio. Not just for sRGB, but for any color space (display-p3, Lab, and so on).

Lea and I have been working on a more modern, object oriented library for color conversions. We would be happy to demonstrate this at the next virtual F2F. The two produce equivalent results.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Color Conversion and Contrast Ratio.

The full IRC log of that discussion <fantasai> Topic: Color Conversion and Contrast Ratio
<astearns> github: https://github.com//issues/989
<leaverou> CSS Color 4 sample code: https://drafts.csswg.org/css-color-4/conversions.js and https://drafts.csswg.org/css-color-4/utilities.js
<fantasai> Rossen___: This issue motivated by TAG review about addition of lch and lab color spaces
<fantasai> Rossen___: One concern being discussed being discussed with TAG was that we were getting more variety of color across platform
<fantasai> Rossen___: but capabilities of simple things like contrasting two colors is very difficult
<fantasai> Rossen___: One of the ideas was, hey, if we have a strongly defined type of color that we can use across platform
<fantasai> Rossen___: then we could look at exposing variety of functions either on or around object
<fantasai> Rossen___: and achieve objectives like a11y and other things
<fantasai> Rossen___: Seemed like TypedOM is good place to start
<fantasai> Rossen___: Color is a type we need to define strongly
<fantasai> Rossen___: Luckily Lea and Chris jumped in, had been thinking about it
<fantasai> ?: ??
<fantasai> chris_: in color 4 there was an appendix written in JS by which I mean Pascal
<fantasai> chris_: It's simple, does work, set of simple functions
<fantasai> chris_: Also have utilities.js
<fantasai> chris_: includes a contrast function
<fantasai> chris_: Here's an sRGB_to_LCH
<fantasai> chris_: it does it all in the right order
<fantasai> chris_: It was useful for examples
<fantasai> chris_: and useful for color 5
<fantasai> chris_: but this is not a proposal for a color model
<fantasai> chris_: not object oriented
<fantasai> chris_: it's just something that wroks
<fantasai> chris_: Here's color.js
<fantasai> chris_: Until this morning was a private repo, now public
<leaverou> https://colorjs.io/
<fantasai> chris_: also not a proposal, but it's object oriented
<fantasai> chris_: This is a JS API, you can use it in the browser or on the server
<fantasai> chris_: These examples are all live, you can edit directly in the web page if you want
<fantasai> chris_: variety of color models, includes all in color 4 (except device-cmyk()) as well as a few more
<fantasai> leaverou demos
<fantasai> chris_: Notice these are in different color spaces
<fantasai> chris_: Internally it goes into CIEXYZ, and then ??, and then gets you a contrast
<fantasai> chris_: You just say you want contrast between two colors, and it just works out for you
<fantasai> chris_: You can change lightness or chroma or whatever
<fantasai> chris_: similar to things we do in Color 5
<fantasai> chris_: Convert between color spaces
<fantasai> chris_: interpolate between colors
<fantasai> chris_: either discreet steps, or gradients, or that sort of thing
<fantasai> chris_ reviews documentation
<fantasai> chris_: Color object. Can give a CSS string or use initializer with coordinates
<fantasai> leaverou: color space ID plus coordinates plus optional alpha
<fantasai> leaverou: or another color
<fantasai> s/color/Color/
<fantasai> chris_: This is similar to color-5, adjusting named coordinates
<fantasai> chris_: We've actually supported more than Color 4 supports
<fantasai> chris_: might be interesting to see if any would be useful as future additions
<fantasai> chris_ notes there's bugs, especially in the documentation, since this is pre-release
<fantasai> chris_: You can change color coordinates. Don't even have to change coordinates of the color space you're in
<fantasai> chris_: That's fairly useful
<fantasai> chris_: We also do gamut-mapping
<fantasai> chris_: because easy to get colors that are out of gamut
<fantasai> chris_: we've worked on that quite a bit, have an algo that works rather well
<fantasai> chris_: Do a binary search to find closest color via chroma reduction
<fantasai> chris_: and do speculative ???
<fantasai> chris_: 1st one we reduce chroma until it's inside the range
<fantasai> chris_: 2nd one, at each stage, we see if we clipped here, would we be close?
<fantasai> chris_: and that works much better
<astearns> s/???/clipping/
<fantasai> chris_: thinking to spec that in color-4 spec
<fantasai> chris_: Interpolation
<fantasai> chris_: range function allows that and getting intermediate stops
<Rossen___> q
<Rossen___> q+
<fantasai> leaverou: range function actually returns a function
<fantasai> leaverou: we can specify which space to do interpolation in
<fantasai> leaverou: you can see here examples of what each interpolation space produces
<fantasai> leaverou: we also implemented longer/shorter/increasing/decreasing args for the hue we were discussing
<fantasai> leaverou: although didn't implement dbaron's ? yet
<fantasai> chris_: Lets us implement and check and see if it works. Very helpful in writing spec
<fantasai> chris_: Also discussing keeping ? constant
<fantasai> leaverou: but we do keep Nan for chroma
<fantasai> s/keeping ?/using Nan for keeping coord/
<fantasai> chris_: It's on GH and there's a link, and also a bunch of tests
<fantasai> chris_: any questions at this stage?
<astearns> ack Rossen___
<fantasai> Rossen___: First of all, this is awesome, thanks for sharing
<fantasai> Rossen___: Looking forward to playing with the project
<fantasai> Rossen___: that's exactly what I was hoping to see
<fantasai> Rossen___: and you made this fantastic
<fantasai> Rossen___: Wrt functions like color-mix() etc.
<fremy> big +1 this is super great!
<fantasai> Rossen___: let's say we start going towards adopting such a type in TypedOM, where does that leave us?
<AmeliaBR> q+
<fantasai> chris_: You'll have 2 ways to do it: declarative in color-5, and imperative way like this
<fantasai> chris_: imperative can have more functionality
<fantasai> chris_: I don't think it's a problem that we have both declarative and imperative
<fantasai> leaverou: ?
<fantasai> leaverou: haven't done adjusters yet
<fantasai> leaverou: accepts a color space as well, but not adjusters
<fantasai> chris_: As general goal, would like to implement all of color-5 so we can test, and do example, see how that works
<fantasai> chris_: Another thing ppl might have noticed, there's a few more color spaces here not in color 4
<fantasai> chris_: support high dynamic range coors
<fantasai> chris_: there's a secret spec called css-color-hdr
<fantasai> chris_: there was an issue around high dynamic range
<fantasai> chris_: I said we won't do it, because too unstable
<fantasai> chris_: but I did spec an extension to color-4
<fantasai> chris_: and wanted to see that it works and coded it up
<fantasai> chris_: I presented to ??? and got good feedback, currently incorporating that
<fantasai> chris_: will present to the WG later
<astearns> s/???/ICC/
<fantasai> chris_: in the meantime, i'm incubating it in code to see whether it's feasible
<astearns> ack AmeliaBR
<florian> https://drafts.csswg.org/css-color-hdr/
<leaverou> https://drafts.csswg.org/css-color-hdr/
<fantasai> AmeliaBR: Great library, very useful. Some similar things, but this is a nice APi with good features
<fantasai> AmeliaBR: Wrt what we should adopt into the actual Web platform
<fantasai> AmeliaBR: I do like the idea of having general color utilities object
<fantasai> AmeliaBR: That you can call without having to getComputeStyle
<fantasai> AmeliaBR: coordnate with TypedOM also good
<fantasai> AmeliaBR: so you can construct CSS color type or get it from a style rule or a computed style
<fantasai> AmeliaBR: that would be great design
<fantasai> AmeliaBR: Probably don't want quite as many features as we have in this library
<fantasai> AmeliaBR: Might want to integrate a bit more e.g. generated gradients
<fantasai> AmeliaBR: and easing function would be its own object, to use more generally than just color
<fantasai> AmeliaBR: Interpolator for data vis
<fantasai> AmeliaBR: would be a great feature, use native interpolation that CSS already knows how to do
<fantasai> AmeliaBR: with additional smarts like interpolating in different color spaces
<fantasai> AmeliaBR: also useful to have
<fantasai> astearns: Anything else besides showing new cool code?
<fantasai> Rossen___: How do you see this moving forward?
<fantasai> chris_: Requirements, one of them for web platform API
<fantasai> chris_: what features do we want, what would be nice, what would be layered on top
<fantasai> chris_: Rossen asked about contrast, that's important
<fantasai> chris_: Converting between color spaces without having to understand how it does
<fantasai> chris_: not knowing about white points, not having to figure that out, that's important
<fantasai> leaverou: There should also be way to access color before / after gamut mapping because ???
<fantasai> AmeliaBR: Especially important for finding contrast ratio
<fantasai> AmeliaBR: if colors are theoretically good contrast, but not on user's screen, need to reflect that
<fantasai> florian: So is the plan to subset your project into TypedOM? and then build your project on top of that result?
<fantasai> chris_: would be reasonable
<fantasai> astearns: If you can't build on top of the subset, then we chose the wrong subset
<fantasai> Rossen___: That was part of my hope
<fantasai> Rossen___: exactly why I was provoking this type of discussion and exposure in typed OM space
<fantasai> Rossen___: Anything else left on color that you didn't cover?
<AmeliaBR> s/ ???/ that affects the results/
<fantasai> leaverou: ICC profiles
<fantasai> leaverou: in theory, TypedOM should cover that as well
<fantasai> leaverou: but wouldn't that make it asynchronous?
<fantasai> TabAtkins: We already have a few things that need external resources, don't have a great way to handle that
<fantasai> TabAtkins: but nothing else needs to be infected, just wait for them via Promise
<fantasai> chris_: Mentioned that we have a lot of stuff. Because we wanted to test things against each other
<fantasai> chris_: e.g. deltaE, implemented 5 different variants
<fantasai> chris_: wanted to compare visual result, perf
<fantasai> faceless2: ...
<fantasai> florian: Feels like what we need is the various objects and methods to let you get from one to the other, and create mixes
<fantasai> florian: don't necessarily need all the operations to get from one color to another color
<fantasai> florian: maybe need ? and ?, but methods to get between them, but TypedOM doesn't need
<fantasai> chris_: Do need an intermediate way to go between colors
<fantasai> chris_: you use colors together, not in isolation
<Rossen___> q?
<fantasai> AmeliaBR: Base case would be converting single color into other color spaces
<fantasai> AmeliaBR: so you can convert two colors into the same color space in order to compare or calculate
<fantasai> AmeliaBR: Devs can implement the formulas that use whatever paramterization of colors that they need
<fantasai> chris_: yep
<fantasai> Rossen___: I agree
<fantasai> Rossen___: that was initial motivation here, exposing the type that will allow you to at least hoist the color space and its values
<fantasai> Rossen___: having this type, you can start adding libraries around it that do a bunch of math
<fantasai> Rossen___: as we go forward, can identify which math goes into native platform and which stays as library
<fantasai> Rossen___: but not having basic type is a blocker
<fantasai> Rossen___: My hope and ask for you, is to start defining what this type should look like
<fantasai> Rossen___: what is minimum set of parameters and stuff
<fantasai> Rossen___: I see Tab and fremy still editing TypedOM, so work with them to move it forward
<astearns> ack fantasai
<fantasai> fantasai: I want to note that Typed OM has also not been published since 2018.

@Qix-
Copy link

Qix- commented May 12, 2021

Excited to hear you're prototyping something! Eventually having a standardized Color constructor living on CSS.Color seems like a natural fit here, IMHO.

As the maintainer of color I agree. I simply strongly caution against letting it become a kitchen sink. I would love to see color be obsoleted by standard browser functionality at some point, to be completely honest.

@svgeesus
Copy link
Contributor

@atanassov wrote:

Further, it would be great to have a function that enables contrast ratio calc given any two colors. The expectations for color contrast described by WCAG are rather detailed and lack developer ergonomics

The WCAG contrast ratio is detailed enough, for sRGB only, but lacks explanation. However it is easy to work out what is being done - the relative, D65-adapted XYZ is calculated for the two colors and the luminance (Y) is used to calculate the contrast.

Given that, it is trivial to extend to other RGB spaces (whether they use D65 or not) and to XYZ, Lab and LCH. Color.js does this, so you can ask for a contrast ratio between any pair of colors regardless of what colorspace each was originally specified in.

@Myndex
Copy link
Member

Myndex commented May 19, 2021

@atanassov wrote:

Further, it would be great to have a function that enables contrast ratio calc given any two colors. The expectations for color contrast described by WCAG are rather detailed and lack developer ergonomics

@svgeesus
The WCAG contrast ratio is detailed enough, for sRGB only, but lacks explanation. However it is easy to work out what is being done - the relative, D65-adapted XYZ is calculated for the two colors and the luminance (Y) is used to calculate the contrast.

Given that, it is trivial to extend to other RGB spaces (whether they use D65 or not) and to XYZ, Lab and LCH. Color.js does this, so you can ask for a contrast ratio between any pair of colors regardless of what colorspace each was originally specified in.

However, the ratio as expressed by the WCAG 2.x math is of questionable utility, as it is not relative to perception as we've discussed elsewhere. As WCAG 2.x contrast ratios do not follow visual perception, the ratio expressed is meaningless, and therefore scaling it to other spaces will carry that same meaningless presentation that does not predict the perception of contrast of a self-illuminated display. WCAG 2.x "4.5:1" is not even remotely consistent in appearance across the range of lightness on the small colorspace of an sRGB monitor, and I should think that scaling to much larger spaces will only exacerbate this problem.

A similar problem exists with Weber, Mod-Weber, and Michelson, as they are all set to predict contrast at threshold for the JND, but become increasingly inaccurate at suprathreshold levels. Suprathreshold contrast prediction is what is needed to give designers useful guidance for readability/discernibility.

At the moment, the implementation of contrast prediction for Silver/WCAG 3.0 is the APCA (derived from SAPC) which is a suprathreshold perceptual contrast appearance model. Presently it is aligned with the sRGB transfer curve, using a standardized observer with ambient luminance at 20% of display max white.

It is sensitive to ambient levels, spatial frequency, and other factors — and for HDR there is the question of where "page white" and "peak white" are mapped (not to mention the different HDR TRC types). Fitting to different transfer curves or gamma, and different expected environments, and as well considering certain adaptive technologies, adds significant complexity as far as selecting the various constants & exponents.

From an accessibility perspective, the coordinates for the primaries of a given colorspace will have an effect on useful choices of constants for improving accessibility with certain impairments.

This leads us to question if we need considerations of things like the H-K effect on perceived contrast — though for readable content, we are mostly interested in font contrast against a background that helps get stimuli to the Visual Word Form Area (VFWA), a pre-lexical processing of whole words and letter pairs, needed for best readability and reading speed.

Current research indicates that this processing path relies on the luminance component, and not chroma. Nevertheless, hue & chroma have implications for various impairments and other visual issues such as chromatic aberration, glare, scatter, and CVD. As such even a perceptual contrast based only on perceived lightness (derived from calculated luminance) presents challenges for accessibility with tristimulus color models.

TLDR

All of this is a long way to say that these (SAPC/APCA/RLAB/CAMxx/etc) methods for contrast appearance prediction are certainly scalable to different spaces, but not necessarily trivial if the goal is a perceptual uniformity across the various colorspaces.

If we assert that perceptual uniformity is desired for the contrast metric to be useful, then the extra effort for such scaling/mapping is warranted. There are some enhancements I have not made public yet that may become helpful for some of these more complex issues, but still under evaluation.

Andy

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

No branches or pull requests

9 participants