w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 657 forks source link

[css-colors] Preserve powerless analogous components? #8484

Open nex3 opened 1 year ago

nex3 commented 1 year ago

In CSS Color 4, when a color is converted between color spaces, any powerless components in the destination space are converted to missing components. This has some odd edge cases when converting between color spaces with analogous components: colors can jump in surprising and observable ways when conversions are involved.

Consider for example a variable --source that's set to animate from hsl(240deg 100% 50%) to hsl(240deg 100% 0%). This is then used in linear-gradient(in oklch, var(--source), red). The middle of this gradient will be consistently purple until the end of the animation at which point it will abruptly switch to pure red, because hsl(240deg 100% 0%) converts to oklch(0 none none).

When converting between color spaces with analogous components, there is a meaningful and well-defined value even for a powerless component. In this case, the value of the oklch hue is the limit as l approaches 0 of hslToOklch(240deg, 100%, l), or 264.0520206381deg. This is even somewhat feasible to compute by converting hsl(240deg 100% 0.0000001%) to oklch and substituting in the resulting hue value.

All that said, that is an extra computation that would need to be done any time an implementation converts a color with a non-missing channel to a space where the analogous channel is powerless. I think it makes the result strictly more in line with user expectations, but I'm not well-equipped to judge whether the edge case is meaningful enough to be worth the spec complexity or implementation weight—so I bring it to you to do with what you please.

svgeesus commented 1 year ago

Thanks for pointing out the unwelcome discontinuous behavior of missing values when two interpolations are running, though, and one goes powerless at the end. That is a great example. And it is caused by the modal behavior of missing values: they either have power or they don't, rather than having a smooth fade off in power (which seems much harder to specify).

So for the simple case of, say, converting between two polar color spaces, this is why we call them analogous components and not identical components. It is intended to be a reasonable midway point between "make everything 0, so reddish for hue" and the sort of careful back-substitution that you describe. And it gives more-expected results in single interpolations.

But yeah that discontinuity can be awkward.