-
Notifications
You must be signed in to change notification settings - Fork 664
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-5] Gamut mapping in HSL/HWB #7107
Comments
As another point of confusion, Example 7 in the spec shows this example: color-mix(in hsl, color(display-p3 0 1 0) 80%, yellow); It says that the P3 color is equivalent to |
EDIT: Ignore this |
I'm going to walk back what I said a little. I'm positive I've run into some cases in the CSS spec that have not been updated, but this doesn't appear to be the case here. Unless I'm missing something, it seems the test is mixing in |
@devongovett thanks for raising this. Also, I wasn't aware of parcel-css and it looks like an interesting tool for authoring in more modern CSS while still covering older browsers.And if you are implementing CCSS gamut mapping in Rust, I would be interested to know whether you found the specification sufficiently clear. Specification wise:
Implementation-wise, @facelessuser is right that I need to finish off and then land the CSS Gamut mapping code in color.js, which is currently off in a branch. Then the individual stages in this sub-test can be evaluated and the expected result checked. @weinig you wrote this test, could you share the working for this sub-test? And does it do extended sRGB to in-gamut sRGB gamut mapping in oklch or was it written at a time when it was specified to use CIE LCH? The test itself just mentions that it is testing that naive clipping is not used. |
In Calculating the result of color-mix, which says (my emphasis):
They are, for all the predefined RGB spaces which use the extended range (component values not not clamped to 0.0 .. 1.0). However, HSL and HWB take, as input, an in-gamut sRGB color and thus, gamut mapping will occur at that step. This sRGB to sRGB gamut mapping is computed in OKLCH
Yes, sRGB is an intermediate space; but sRGB to HSL requires the input values to be in gamut because HSL and HWB) cannot represent out of sRGB-gamut colors. |
And thus, the answer to that question is "neither". All CSS gamut mapping occurs in OKLCH. The gamut mapping is triggered by the need to convert an sRGB color to HSL/HWB, which requires an in-gamut color. Ah, I just spotted
needs to be extended to also cover conversion to HSL/HWB. |
Thanks, that makes sense. I think it would be good to call out that gamut mapping should occur before converting to HSL/HSB, as this does not occur with other intermediate color spaces.
Yeah, sorry, I meant the part that converts from OKLCH to the
I would say the individual parts were clear, but what was missing for me was a higher level overview of the whole conversion/interpolation algorithm. I found myself jumping around a fair bit trying to figure out in what order to apply each of the parts, e.g. when and when not to apply gamut mapping, when to replace missing components with |
Oh, another thing specifically about the gamut mapping algorithm that I found by looking at WebKit's implementation was how to deal with colors with OKLCH lightness values that are 0% or >= 100%. There were some tests that didn't pass without handling those edge cases specifically. Example test: test_computed_value(`color`, `color-mix(in hsl, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). However, without the extra conditions that WebKit added for whites and blacks, I get |
@weinig reported that too, and so the spec was fairly recently clarified:
|
Fair comment. Really appreciate getting implementer comments! I will ping again in this issue when I have addressed your concerns and there is updated spec text to review. |
@devongovett ping. I now have a new section in CSS Color 4, Converting colors which lists the steps to go from color1 in some color space src to color2 in some colo space dest. It includes converting missing values to none, and explicitly lists the two cases (displays, and HSL/HWB) where gamut mapping is needed before the next step in the conversion. It also covers chromatic adaptation, if there is a different white point. Please take a look, if it seems ok then I will add examples. Is the list of steps sufficient or would a diagram in addition make it clearer? |
Thanks for the ping @svgeesus! Sorry for the slow response. This is very helpful. 👍 I really liked the diagram in @LeaVerou's recent blog post btw. Something like that might be useful as well. https://lea.verou.me/2022/06/releasing-colorjs/ |
Yes, a subset of that would be a useful addition. |
I am implementing support for
color-mix
in Parcel CSS, and following the tests in WPT. A few tests related to gamut mapping failed in my implementation and I am wondering whether the test is wrong or my understanding of the spec is wrong.Example test:
The test expects
rgb(0, 249, 66)
as the result, but I am gettingrgb(0, 247, 78)
. This seems to be the result of gamut mapping occurring in the sRGB space rather than the HSL space. However, thecolor-mix
in the test states that the color mixing should occur in the HSL space. If I convert the HSL color to sRGB before gamut mapping, and then back to HSL afterward for interpolation the test passes. However, I don't see where in the spec that is required. It says:In this case, we're converting from OKLCH to HSL, and then comparing the clipped result via deltaE, so I would consider sRGB to be an intermediate space.
So my question: does gamut mapping happen in the sRGB space for HSL and HWB colors, or in the HSL/HWB space?
Hopefully that made sense...
The text was updated successfully, but these errors were encountered: