csswg-drafts icon indicating copy to clipboard operation
csswg-drafts copied to clipboard

[css-color-4] Hue interpolation "specified" should be removed

Open fserb opened this issue 1 year ago • 13 comments

Although it sounds like a reasonable and simple idea, the interpolation method called "specified" by the spec is actually extremely costly and complex to be implemented by UAs. The reason for it is that is breaks a basic assumption about colors, namely, that they (apart from some loss of precision) can be represented and converted between different systems.

UAs usually choose an internal color representation (like sRGBA). Hue-based systems (like HSL, HWB) are, in practice, expected to have Hues defined in the [0, 360) region. Outside of that region, colors can be converted out of them, but not preserved. To allow internal representation of arbitrary Hues, UAs need to have special code to store those types of color representation throughout their pipelines.

We can see a problem caused by this on the current Safari TP implementation of hue specified gradients, where Safari follows the proper algorithm (numeric interpolation of hue values), but fails to preserve their value outside of mod 360 (since they are internally converted to sRGB), creating a weirdly unspecified behavior, that doesn't address the original spirit of the spec (the ability to have multiple rotations on the hue circle in a single gradient interpolation).

Considering that it does seem like a reasonable request, but also understanding that there's no pressing use case for it and that there's a big implementation complexity, we'd like to request that this small section of the spec to be removed from CSS Color 4 and then re-discussed at a later time.

fserb avatar Sep 15 '22 21:09 fserb

Do you have a test case of the issue with gradients you are describing?

weinig avatar Sep 22 '22 20:09 weinig

I don't have access to a Safari to verify this, but the testcase would be to use a "specified" interpolation to go from, say, hsl(0deg 100% 50%) to hsl(720deg 100% 50%) - this should produce two full sweeps thru the hue wheel, per spec.

tabatkins avatar Sep 22 '22 23:09 tabatkins

Oh, interesting, I hadn't realized how unrestrictive the hue notion was. Makes me curious if we are getting serialization wrong as well, as that also ends up being % 360.

weinig avatar Sep 23 '22 01:09 weinig

I don't think this will be a problem for WebKit. The current behavior is just a bug, due to a misreading or misunderstanding of the spec on my part.

I agree this poses a little problem for hsl() and hwb() specifically, as we do currently store them as 8-bit per channel sRGB when no component is "none", but I don't believe that optimization is really doing anything and is more of a historical oddity. We can just as easily move that conversation to serialization time.

I filed https://bugs.webkit.org/show_bug.cgi?id=245552 to track fixing this in WebKit.

weinig avatar Sep 23 '22 02:09 weinig

I whipped up a fix (still a work in progress, I haven't double checked all the math is right), and it's pretty fun. Here is the linear gradient linear-gradient(in oklch specified hue to right, oklch(75% 0.3 -180), oklch(75% 0.3 720)); (existing WebKit top, fixed WebKit bottom). Shiny colors.

Screenshot 2022-09-22 at 7 36 40 PM

weinig avatar Sep 23 '22 02:09 weinig

+1 from us to constraining hue to [0..360]. We had to do some terrible, terrible things to implement this, which I would be very happy to remove.

faceless2 avatar Oct 03 '22 18:10 faceless2

The reason for it is that is breaks a basic assumption about colors, namely, that they (apart from some loss of precision) can be represented and converted between different systems.

I agree that this basic colorimetric assumption is fundamental to the approach in CSS Color 4 and that having to keep around specified hue angles greater than 360 breaks this assumption for little benefit.

Thus, I don't think specified should be moved to a later spec. It should be removed entirely.

@LeaVerou @argyleink @una @tabatkins any objections?

@weinig can you settle for slightly less rainbow fun?

svgeesus avatar Oct 18 '22 16:10 svgeesus

The reason for it is that is breaks a basic assumption about colors, namely, that they (apart from some loss of precision) can be represented and converted between different systems.

I agree that this basic colorimetric assumption is fundamental to the approach in CSS Color 4 and that having to keep around specified hue angles greater than 360 breaks this assumption for little benefit.

Thus, I don't think specified should be moved to a later spec. It should be removed entirely.

@LeaVerou @argyleink @una @tabatkins any objections?

I'll need to think more about it, but I’m not hugely opposed to it. It would certainly make specifying longer a lot easier (see https://github.com/w3c/csswg-drafts/pull/7895 ), and I suppose people can still do rainbows with extra stops.

LeaVerou avatar Oct 18 '22 17:10 LeaVerou

No objections from me.

tabatkins avatar Oct 18 '22 17:10 tabatkins

@weinig can you settle for slightly less rainbow fun?

:). Certainly can. No objection here.

weinig avatar Oct 18 '22 17:10 weinig

no objections

argyleink avatar Oct 18 '22 17:10 argyleink

This would also affect (would make serialization be mod 360)

  • https://github.com/w3c/csswg-drafts/issues/7782

svgeesus avatar Oct 18 '22 19:10 svgeesus

It would certainly make specifying longer a lot easier

That was my thought too.

svgeesus avatar Oct 18 '22 19:10 svgeesus

We didn't get to this item on today's call but it seems there is consensus to remove specified.

svgeesus avatar Oct 26 '22 18:10 svgeesus