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
{{ message }}
Repository navigation
[css-images-4] Undefined Hue angle when interpolating from neutrals #4928
Edit: skip to here to see the interaction with gradient stop interpolation
Noticed by Mike Bostock in the context of D3, but applicable to the color modification functions in Color5, too:
When you interpolate two colors in HCL colorspace, if one of the colors has undefined chroma or hue, the interpolator uses the chroma or hue from the opposite color. This can sometimes result in out-of-gamut colors that cannot be displayed in RGB colorspace. You may therefore wish to use Lab colorspace instead, or to specify the chroma explicitly to disable inheritance.
When interpolating a color whose hue is undefined with a color with a defined hue, it works well for the undefined hue to be considered equal to the defined one.
A lab(L 0 0) color (equivalent to the deprecated gray() syntax) will produce lch(L 0 0). When a color authored in a different color space is converted to lch() and its chroma ends up 0, it's fair to consider its hue undefined, to enable the behavior above. However, when authored in lch() directly, a color with zero chroma (e.g. lch(50 0 0)) I guess we should honor the explicit hue?
Hmm, I haven't fully fleshed out the idea, but could we do a chroma premultiplication (for lch()) or saturation premultiplication (for hsl()) similar to an alpha premultiplication? That would make colors with a small chroma component conntribute less of their hue to the interpolation and might satisfy @tabatkins's math requirements? (Edit: on a more attentive read, @tabatkinsactually suggests this approach. 🤦♂️)
changed the title [-][css-color-5] Undefined Hue angle when interpolating from neutrals[/-][+][css-color-4] Undefined Hue angle when interpolating from neutrals[/+]on Feb 6, 2021
But it's arguably not the "correct" interpolation with noticeably large chroma
That was my conclusion also. A smooth transition away from the NaN fixup works for the "almost zero chroma" case at the expense of making all the small to large chroma values result in non-perceptually-uniform hue ramps. An abrupt transition is awkward. Maybe a fast transition where the chroma is still in the "very tiny but not zero" range?
If one of the angles has the value NaN, then for interpolation, NaN is replaced by the value of the other hue angle. If both angles have the value NaN, then for interpolation, NaN is replaced by the value 0 for both angles.
This avoids the area of not-really-perceptually-uniform by making the cutoff between "has a defined hue" and "achromatic" very close to the achromatic axis, so we et well defined behavior in all cases.
I think for the scope of css-color-4 that note is sufficient. (Since it appears the longer hue interpolation leaves identical angles untouched, I don't see any possible interactions between hue fixup and NaN hues).
In the context of css-images, I assume for gradients this adjustment is made on a piecewise basis. So the #888 in linear-gradient(red, #888, green) gets red's hue on the first segment and green's hue on the second, if the interpolation happens in a cylindrical polar space.
changed the title [-][css-color-4] Undefined Hue angle when interpolating from neutrals[/-][+][css-images-4] Undefined Hue angle when interpolating from neutrals[/+]on Sep 6, 2021
In the context of css-images, I assume for gradients this adjustment is made on a piecewise basis.
Yes, and the spec now says so explicitly.
So the #888 in linear-gradient(red, #888, green) gets red's hue on the first segment and green's hue on the second, if the interpolation happens in a cylindrical polar space.
I have just added that exact example to CSS Images 4.
Activity
[css-color-5] Add interpolation section, define hue angle interpolati…
danburzo commentedon Jul 5, 2020
When interpolating a color whose hue is undefined with a color with a defined hue, it works well for the undefined hue to be considered equal to the defined one.
A
lab(L 0 0)color (equivalent to the deprecatedgray()syntax) will producelch(L 0 0). When a color authored in a different color space is converted tolch()and its chroma ends up 0, it's fair to consider its hue undefined, to enable the behavior above. However, when authored inlch()directly, a color with zero chroma (e.g.lch(50 0 0)) I guess we should honor the explicit hue?danburzo commentedon Jul 14, 2020
Hmm, I haven't fully fleshed out the idea, but could we do a chroma premultiplication (for
lch()) or saturation premultiplication (forhsl()) similar to an alpha premultiplication? That would make colors with a small chroma component conntribute less of their hue to the interpolation and might satisfy @tabatkins's math requirements? (Edit: on a more attentive read, @tabatkins actually suggests this approach. 🤦♂️)I'll try a demo to see if it pans out.
danburzo commentedon Jul 14, 2020
I've made an interactive notebook to try it out. It works surprisingly well! It handles graciously and continuously zero, and near-zero, chroma:
But it's arguably not the "correct" interpolation with noticeably large chroma:
[-][css-color-5] Undefined Hue angle when interpolating from neutrals[/-][+][css-color-4] Undefined Hue angle when interpolating from neutrals[/+]svgeesus commentedon Feb 6, 2021
That was my conclusion also. A smooth transition away from the
NaNfixup works for the "almost zero chroma" case at the expense of making all the small to large chroma values result in non-perceptually-uniform hue ramps. An abrupt transition is awkward. Maybe a fast transition where the chroma is still in the "very tiny but not zero" range?svgeesus commentedon Sep 3, 2021
Currently, the spec says
(we already have Achromatic colors converted to hue-ish spaces should treat hue as "missing", not NaN so don't focus on the specific
NaNormissing)This avoids the area of not-really-perceptually-uniform by making the cutoff between "has a defined hue" and "achromatic" very close to the achromatic axis, so we et well defined behavior in all cases.
Is that sufficient, or is more needed?
danburzo commentedon Sep 4, 2021
I think for the scope of
css-color-4that note is sufficient. (Since it appears thelongerhue interpolation leaves identical angles untouched, I don't see any possible interactions between hue fixup andNaNhues).In the context of
css-images, I assume for gradients this adjustment is made on a piecewise basis. So the#888inlinear-gradient(red, #888, green)getsred's hue on the first segment andgreen's hue on the second, if the interpolation happens in a cylindrical polar space.[-][css-color-4] Undefined Hue angle when interpolating from neutrals[/-][+][css-images-4] Undefined Hue angle when interpolating from neutrals[/+]svgeesus commentedon Sep 6, 2021
Thanks for the confirmation regarding css color 4.
Re-tagging to css images and leaving open, so we don't forget
[css-color-4][editorial] #4928 no longer tagged css-color
[css-images-4] Explicitly link to CSS Color 4 hue interpolation and h…
[css-images-4] Add example of missing hues when interpolating with ne…
svgeesus commentedon Dec 12, 2023
@danburzo wrote:
Yes, and the spec now says so explicitly.
I have just added that exact example to CSS Images 4.