Skip to content

[css-color] Serializing color() values #480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
grorg opened this issue Sep 14, 2016 · 19 comments
Closed

[css-color] Serializing color() values #480

grorg opened this issue Sep 14, 2016 · 19 comments
Assignees

Comments

@grorg
Copy link
Contributor

grorg commented Sep 14, 2016

How should values defined using color() be serialized in computed style?

  1. Should color(a b c) or color(srgb a b c) values be output as rgb()?
  2. Should color(someprofile a b c) values that end up inside sRGB be output as rgb()?
@SebastianZ
Copy link
Contributor

SebastianZ commented Sep 14, 2016

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

@svgeesus
Copy link
Contributor

I agree with Tab and SebastianZ

@svgeesus svgeesus added the css-color-4 Current Work label Sep 14, 2016
@grorg
Copy link
Contributor Author

grorg commented Sep 14, 2016

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.

@upsuper
Copy link
Member

upsuper commented Sep 17, 2016

Agree with @grorg, unless someone can prove that changing this output is web-compatible.

@grorg
Copy link
Contributor Author

grorg commented Nov 11, 2016

Wow. I'm regretting my last statement now.

@cabanier
Copy link
Member

:-(
It's all your fault!

@frivoal
Copy link
Collaborator

frivoal commented Nov 30, 2016

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:

  • This is not entirely clear what is meant by that. The simplest interpretation is that the value should be computed to the rgba() function, but maybe something else is intended.
  • If computing to 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.
  • Browsers today (checked Chrome, Firefox, Safari, Edge, Presto) interoperably return 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()).
  • How to convert 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()...

frivoal added a commit to frivoal/csswg-drafts that referenced this issue Jan 9, 2017
This is a first pass at providing a centralized definition of how all
<<color>> values are treated at computed value and used value time.

This relates to w3c#741, w3c#480, w3c#867
@css-meeting-bot
Copy link
Member

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.

@grorg
Copy link
Contributor Author

grorg commented Apr 21, 2017

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%).

@zcorpan
Copy link
Member

zcorpan commented Apr 24, 2017

Should this go into cssom?

@tabatkins
Copy link
Member

Probably, yes.

@zcorpan zcorpan added the cssom-1 Current Work label Apr 25, 2017
@zcorpan zcorpan self-assigned this Apr 25, 2017
@frivoal
Copy link
Collaborator

frivoal commented Apr 25, 2017 via email

@svgeesus
Copy link
Contributor

@zcorpan zcorpan removed their assignment Dec 4, 2017
@csnardi
Copy link
Contributor

csnardi commented Jan 23, 2018

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".

@svgeesus
Copy link
Contributor

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!

@css-meeting-bot
Copy link
Member

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 number
  • 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).
The full IRC log of that discussion <stantonm> topic: Serializing color() values
<astearns> github: https://github.com//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).

@svgeesus
Copy link
Contributor

@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: 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).

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.

@svgeesus
Copy link
Contributor

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).

@svgeesus
Copy link
Contributor

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants