[csswg-drafts] [css-color-4] Spec isn't clear whether powerless check or carryover check is done first (#8602)

tabatkins has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-color-4] Spec isn't clear whether powerless check or carryover check is done first ==
In <https://w3c.github.io/csswg-drafts/css-color/#powerless> we say that extreme values of some components (like a 0 chroma) make other components (like hue) "powerless" - they can't affect the result so any value is exactly equivalent. When a color with such a component is produced by color space conversion, we treat the powerless components as missing, so interpolation doesn't work with an arbitrary nonsense value for the powerless component.

In <https://w3c.github.io/csswg-drafts/css-color/#interpolation-missing> we define that if you're interpolating colors that need to be converted into the interpolation space, any missing components will be "carried forward" to analogous components in the result of the conversion, again so you don't interpolate with a nonsense value. A missing hue from hsl() becomes a missing hue for oklch(), etc.

What we don't define is the relative ordering of these two operations when they both apply.

In <https://github.com/w3c/csswg-drafts/issues/8563#issuecomment-1472323517> gives an example where an `hsl(90deg 50% none)` color is interpolated in oklch space with another color. The two possible orders produce very different results.

* If the powerless check comes first, then we first convert the hsl color, getting `oklch(0 0 0)`. That has a zero lightness, rendering both chroma and hue powerless, resulting in `oklch(0 none none)`. Then we carry forward the missing lightness from the original color, getting `oklch(none none none)`.
* If the carry-forward comes first, we again first get `oklch(0 0 0)`. Then we carry forward the missing lightness, giving `oklch(none 0 0)`. Then we check for powerlessness - a zero chroma renders the hue powerless, giving `oklch(none 0 none)`.

Both results end up just taking the lightness and hue from the opposing color, but they differ on whether they interpolate the chroma or just take it.

I think the second option (carry-forward is done first) makes the most sense. We got black because we filled in the missing lightness with 0 (since we need *some* number to do the conversion); immediately paying attention to that fake zero lightness doesn't seem correct.

-------

I was hoping we could define an even friendlier option that "carries forward" non-missing components too, if the missing component's "default value" we used for conversion renders other components powerless. (After all, the 0 chroma we got in the result above is just as fake as the 0 lightness, since it came about *due to* the fake 0 lightness.) But unfortunately "analogous component" doesn't mean "easily convertable" component; you can't just carry forward a `90deg` hsl hue into an oklch hue, or similarly for chroma.

So this just confirms that manually using `none` is a tool for authoring convenience and requires control over all parts of the transition; we can't actually do smart things with it when conversions start happening.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/8602 using your GitHub account


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

Received on Thursday, 16 March 2023 17:42:07 UTC