You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 #8563 (comment) 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.
The text was updated successfully, but these errors were encountered:
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 #8563 (comment) 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.oklch(0 0 0)
. That has a zero lightness, rendering both chroma and hue powerless, resulting inoklch(0 none none)
. Then we carry forward the missing lightness from the original color, gettingoklch(none none none)
.oklch(0 0 0)
. Then we carry forward the missing lightness, givingoklch(none 0 0)
. Then we check for powerlessness - a zero chroma renders the hue powerless, givingoklch(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.The text was updated successfully, but these errors were encountered: