How should values defined using color() be serialized in computed style?
I tend to agree with Tab's statement to treat rgb()/rgba() as legacy syntax. Therefore I think it should compute to color(a b c) and color(a b c / d) in those cases.
Sebastian
I agree with Tab and SebastianZ
Treating it as legacy syntax is fine for input. But the output from computed style is probably parsed by a lot of content on the Web. If that all of a sudden changes to something unexpected, the world will collapse, the seas will rise, and Trump may get elected.
Agree with @grorg, unless someone can prove that changing this output is web-compatible.
Wow. I'm regretting my last statement now.
:-(
It's all your fault!
Reposting a comment I made in #742 as I am closing that one as duplicate:
The css-color-4 definition of the computed value of the color property says :
Computed value: an RGBA color
That doesn't sound right:
rgba() function, but maybe something else is intended.rgba() is intended, this appears to contradicts css-color-3. The rule there is phrased in a somewhat ambiguous way, but seems to imply that basic colors, hex colors, and rgb() colors should be computed to the six digit hex value or rgb() functional value, while other notations should be preserved as specified.rgb() (not rgba()) as the computed value of hex colors or named colors when exposing it through getComputedStyle. In contradiction of css-color-3, All also do so for hsl() colors. And but all but Edge also for rgba() and hsla() colors with an alpha of 1 (Edge compute both to rgba()).color() colors to rgba() is non trivial and lossy. It needs to happen eventually to be able to paint, but computed value time seems wrong.If the level 4 text is meant to be different from the level 3, we should errata level 3, and be clearer about what exactly is meant. But given the compat data and the newer color functions, neither "always rgba()" nor “as specified, except but #rrggbb rgb() and named colors” seems to be the right answer. I think we should specify what is already inter-operable (and see if Edge is willing to join everyone else on computing rgba(*,*,*,1) and hsla(*,*,*,1) to rgb().
The new color functions that do not yet have a compat baggage, so we should probably be clear before they get one. We could keep them as specified, or maybe convert them to a base notation: gray()and lch() -> lab(), hwb() and hwb()-> color(), omit the alpha component when it is 1.
As for the comma-less version of rgb() and hsl(), we also should decide if the compute to the legacy syntax (with commas), preseve them as written, or compute to color()...
The CSS Working Group just discussed Serializing color() values, and agreed to the following resolutions:
RESOLVED: color() always serializes as color().The full IRC log of that discussion
<dino> Topic: Serializing color() values
<dino> Github Topic: https://github.com/w3c/csswg-drafts/issues/480
<TabAtkins> dino: If you did "color(srgb 1 0 0)", should it serialize as that, or as "rgb(255 0 0)"?
<TabAtkins> dino: Two problems.
<TabAtkins> dino: We lose a lot of precision sending it out to rgb() - only 8 bits of precision, vs doubles.
<TabAtkins> dino: That's impacted us in real impls - the touch bar in new macs, when in editting mode you can pick a color, and those colors are in a wider color space, then if we convert to srgb you lose precision; if we send that information back up, it's not what the author said.
<TabAtkins> ChrisL_: In general I've moved Color 4 to 0-1, because it's inherently bit-depth neutral, and we're seeing devices with 10 or 12 bits per channel now.
<TabAtkins> dino: So should a color(srgb) be output as rgb()?
<TabAtkins> ChrisL_: If anything, output it as %, that's higher precision.
<TabAtkins> TabAtkins: Or just keep it color().
<TabAtkins> dino: That's what I do now. It's higher precisions.
<TabAtkins> TabAtkins: Does anyone suggest simplifying to rgb()?
<TabAtkins> dino: No, it's just not strictly defined.
<TabAtkins> dino: And now that we have the new rgb() syntax, should we serialize to that? That would probably break things.
<TabAtkins> TabAtkins: Yeah, I think we need to output in the old rgb().
<TabAtkins> dbaron: Back to color(), we could output to % and keep it higher-depth.
<TabAtkins> dino: Yeah, but it would probably break content.
<TabAtkins> dino: No content expects %s in the serialized form right now.
<TabAtkins> dino: So maybe we can suggest that rgb() is always 8-bit?
<TabAtkins> ChrisL_: Absolutely not - rec2020 is only defined over 10 and 12 bit. It woudl be a syntax violation.
<TabAtkins> dbaron: I think he was suggesting that the rgb() syntax, specifically, is 8-bit.
<TabAtkins> ChrisL_: Okay, that's fine. That then means that rgb() *must* be stuck in sRGB - it can't become rec2020.
<TabAtkins> dino: No, I really just meant that when we serialize rgb(), we round it to 8-bit.
<TabAtkins> ChrisL_: So if a user inputs with rgb(%), then serializes, what do you get?
<TabAtkins> TabAtkins: integers between 0 and 255
<TabAtkins> dino: So I think we cna resolve that color() serializes as color().
<TabAtkins> RESOLVED: color() always serializes as color().
<TabAtkins> TabAtkins: Make sure to specify whether trailing 0 args are omitted or not in serialization.
<TabAtkins> dino: I think I always output all the args. I leave off alpha if it's 1.
Resolved. An input of "color" always serializes as "color" Everything else is undefined.
Extra requirement is that "color" serialization doesn't truncate trailing 0 values. e.g. color(srgb 1 0 0).
It is required to drop the "/ 1" for alpha though (if alpha is 100%).
Should this go into cssom?
Probably, yes.
Shouldn't that rather go to https://drafts.csswg.org/css-color-4/#resolving-color-values https://drafts.csswg.org/css-color-4/#resolving-color-values ?
Shouldn't that rather go to https://drafts.csswg.org/css-color-4/#resolving-color-values https://drafts.csswg.org/css-color-4/#resolving-color-values ?
Yes. Removing color-3 tag.
The issue of serializing colors specified through rgb() with decimal channels still hasn't been resolved; the discussion above seemed to imply that rgb(0.1, 0.1, 0.1) should be serialized to rgb(0, 0, 0) even if the UA does not round the channel when painting.
The CSSOM spec is no clearer; first it is said the "shortest base-ten integer serialization" should be used, but the following 7 lines use the "shortest base-ten serialization".
I agree it is not yet resolved. And the integer part would be an issue; particularly for those color systems that use a bit-depth-neutral 0.0 to1.0 range!
The CSS Working Group just discussed Serializing color() values, and agreed to the following:
RESOLVED: color() functions, if they have a choice between percentage and number, they should use numberRESOLVED: the `color(lab ...)` function, like the rest of the color() values, are in the 0-1 (or 0% - 100%) range. And they serialize the same as other color() values (as a 0-1 number).The full IRC log of that discussion
<stantonm> topic: Serializing color() values
<astearns> github: https://github.com/w3c/csswg-drafts/issues/480
<stantonm> chris: dean raised how does the color function get serialized
<stantonm> ... whats a good serialization, for all the new ones they need to be floats
<stantonm> ... any problems with that in OM
<stantonm> TabAtkins: if it's not int it will serialize property, as long as data model underneath is number
<stantonm> chris: for color you can use 0-1, or 0-100%
<stantonm> ... 0-1 was simpler
<stantonm> emilio: consistent with alpha
<stantonm> RESOLVED: color() functions, if they have a choice between percentage and number, they should use number
<stantonm> chris: lightness is a percent, how do we handle that specific one
<stantonm> TabAtkins: percentage and number equilivence is defined as 0-1 equals 0-100%
<stantonm> ... so we can just accept number
<stantonm> s/can/can't/
<stantonm> ... in the color function, just follow the rules - which is 0-1
<stantonm> fantasai: agree with tab
<stantonm> florian: for match function we take 0-100?
<stantonm> christ: eventually caved to just take percent
<stantonm> TabAtkins: could be this one color space takes 0-400, so doesn't matter
<stantonm> chris: some people use equipment that gives back percent
<stantonm> fantasai: adding the percent sign makes sense
<chris> s/gives back percent/gives back L in 0 to 100 range and no percent
<stantonm> TabAtkins: don't do the weird thing with lab and percentages (?)
<stantonm> chris: did it for rgb, so we argued it might make sense for lab
<stantonm> ... it's longer so not being used as much
<AmeliaBR> We already have RGB functions where percentages map to 0-255 in integers. Because that's the convention for that data type. If integer 0-100 is the convention for lab.
<AmeliaBR> ... maybe makes sense to follow.
<fantasai> in the color() function?
<AmeliaBR> Ummm… I don't know which syntaxes are allowed there.
<TabAtkins> Proposed Resolution: the color(lab ...) function, like the rest of the color() values, are in the 0-1 (or 0% - 100%) range. And they serialize the same as other color() values (as a 0-1 number).
<stantonm> RESOLVED: the color(lab ...) function, like the rest of the color() values, are in the 0-1 (or 0% - 100%) range. And they serialize the same as other color() values (as a 0-1 number).
@grorg wrote:
Resolved. An input of "color" always serializes as "color" Everything else is undefined.
Extra requirement is that "color" serialization doesn't truncate trailing 0 values. e.g. color(srgb 1 0 0).
It is required to drop the "/ 1" for alpha though (if alpha is 100%).
Those two resolutions are now in the specification
@csswg wrote
RESOLVED: color() functions, if they have a choice between percentage and number, they should use number
RESOLVED: thecolor(lab ...)function, like the rest of the color() values, are in the 0-1 (or 0% - 100%) range. And they serialize the same as other color() values (as a 0-1 number).
Those two as well.
However, on the 22 Oct 2020 TPAC call, it was also resolved to split out serialization from the specified, computed, used and actual values section into a new section, and I am still working on that, so leaving this open for now.
The css-color-4 definition of the computed value of the color property says :
Computed value: an RGBA color
That doesn't sound right:
The spec no longer says that. Hasn't for some years. (I'm just going through the thread again to be sure nothing was missed).
All dealt with, CSSWG resolutions implemented, see see Serializing sRGB values
Should color(a b c) or color(srgb a b c) values be output as rgb()?
No, they are output as color()
Should color(someprofile a b c) values that end up inside sRGB be output as rgb()?
No, they are output as color() as well.
@grorg do these edits resolve all of your concerns?
Most helpful comment
Treating it as legacy syntax is fine for input. But the output from computed style is probably parsed by a lot of content on the Web. If that all of a sudden changes to something unexpected, the world will collapse, the seas will rise, and Trump may get elected.