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

[css-color-4] Serialization of named colors

Open GPHemsley opened this issue 2 years ago • 7 comments

The spec says that named colors (including transparent) resolve to their rgb()/rgba() values. However, it appears that Firefox, Chrome, and Edge, at least, serialize to their literal (lowercase) names.

Should the spec be changed?

GPHemsley avatar Oct 12 '22 04:10 GPHemsley

You might be interested by the comments starting from this https://github.com/w3c/csswg-drafts/issues/1004#issuecomment-1061910466.

cdoublev avatar Oct 12 '22 10:10 cdoublev

You might be interested by the comments starting from this #1004 (comment).

@cdoublev I am indeed. You're always a step ahead of me. :)

Can't say I understand anything any better, though. :/

I'm working on some wpt tests that might enlighten us all.

GPHemsley avatar Oct 13 '22 00:10 GPHemsley

Yeah, it gives me a headache each time I try to understand how color serialization is defined. The simple answer is that browsers do not always serialize in a conforming way and I think serialization does not have a high priority, be it for browser interoperability or spec authors. I understand it since it is not a feature for end users.

With that said, two people asking the same question may be a sign that the spec can be improved. The part you are linking to defines that a named color is derived from a computed value, but style.color (specified value) is not. Why would it be required to serialize a named color as part of a specified value, to rgb()? I have learned (this should be defined somewhere, imo) that a specified value is meant to represent the value as specified by its author + simplifications from tokenization (lowercase keywords, etc).

Good luck with your WPTs! =)

cdoublev avatar Oct 13 '22 04:10 cdoublev

I discussed a similar issue with @emilio at TPAC and the problem is that most, but not all, of to serialize a CSS value for colors moved to CSS Color 4. The part that remains, and thus makes reading CSS Color 4 about serialization difficult, is:

If is a component of a specified value, then return the color as follows:

  • If the color was explicitly specified by the author, then return the original, author specified color value.
  • Otherwise, return the value that would be returned if the color were a component of a computed value.

That needs to be moved over; in addition, the rule in CSSOM does not reflect what browsers do and needs to be amended to

  • If the color was explicitly specified by the author as a named color, then return the original, author specified color value folded to ASCII-lowercase.

svgeesus avatar Oct 13 '22 16:10 svgeesus

Ah, I was suspecting that the keyword rule may also have been coming into play:

keyword → The keyword converted to ASCII lowercase.

GPHemsley avatar Oct 13 '22 22:10 GPHemsley

@emilio can you confirm that I remembered correctly? If so I can copy-and-edit the remaining portion of color serialization from CSSOM to CSS Color 4.

svgeesus avatar Oct 18 '22 16:10 svgeesus

Related:

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

svgeesus avatar Oct 18 '22 16:10 svgeesus

So, if I'm understanding correctly, serialization (of sRGB, anyway) uses the computed value except when it was specified as a keyword, then it uses the (normalized) specified value?

Any update on the decisions about spec edits? I'm not seeing anything in the minutes beyond publishing a new draft.

GPHemsley avatar Nov 01 '22 05:11 GPHemsley

Was waiting for confirmation from @emilio

svgeesus avatar Nov 01 '22 14:11 svgeesus

Yeah, Chris's comment is right. The only explicitly preserved thing for srgb colors is the keyword.

But it needs to be recursive (e.g., color-mix(red, blue, ..) should use red / blue. It's not necessarily the computed value for all colors, depending on how / when some of the new functions compute.

emilio avatar Nov 09 '22 17:11 emilio

The only explicitly preserved thing for srgb colors is the keyword.

In my experience, there are a lot more specified things that are not preserved: conversion to legacy rgb() or rgba(), removing <alpha-value> >= 1, mapping percentage to numbers, resolving calc values, clamping, precision, etc.

cdoublev avatar Nov 09 '22 17:11 cdoublev

That's what I'm saying right? Everything except the keyword is not explicitly preserved :)

emilio avatar Nov 09 '22 17:11 emilio

Yeah, I spent too much time reading the same sentences today, so I am not able to understand a single one on the first try, even when it iss perfectly clear. Sorry...

cdoublev avatar Nov 09 '22 18:11 cdoublev

@GPHemsley how is the spec looking now? In particular 14.1. Resolving sRGB values and 15.2. Serializing sRGB values

In general I am going through the spec to ensure that each syntactic form of <color> defines a specified value, as well as computed; and in general changing serialization to cover both specified and computed value serialization.

svgeesus avatar Jan 14 '23 15:01 svgeesus

This was also discussed in

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

svgeesus avatar Jan 14 '23 15:01 svgeesus

15.2. Serializing sRGB values

[...]

When serializing the value of a property which was set by the author to a CSS named color, therefore, for the specified value, the (all lowercase) named value is retained.

<system-color>, <deprecated-color>, currentColor, transparent, as components of a speficied value, also serialize to the (all lowercase) named value in Chrome/FF.

I do not understand whether transparent should serialize to the color name or rgb() from the following:

15.6. Serializing other colors

This applies to transparent and currentcolor.

The serialized form of these values is derived from the computed value and uses ASCII lowercase letters for the color name.

The serialized form of transparent is the string rgba(0, 0, 0, 0).

The serialized form of currentColor is the string currentcolor.

The following:

During serialization, any missing values are converted to 0.

contradicts this:

If a color with a missing component is serialized or otherwise presented directly to an author, then for legacy color syntax it represents that component as a zero value

cdoublev avatar Jan 15 '23 13:01 cdoublev

<system-color>, <deprecated-color>, currentColor, transparent, as components of a specified value, also serialize to the (all lowercase) named value in Chrome/FF.

Right, though the section you are quoting from is about sRGB colors. transparent and currentColor are dealt with in Resolving other colors, and currentColor is not necessarily an sRGB color.

(transparent is, though, and should probably be added to Resolving sRGB values). CSS Color 3 only defined the computed value of transparent. Is there value in retaining whether the author used transparent or rgba(0,0,0,0)? I don't have a strong opinion either way, so would follow what implementations currently do.

There is a contradiction in the spec regarding whether system colors are sRGB colors, see

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

svgeesus avatar Jan 17 '23 13:01 svgeesus

The spec already covers the specified value of transparent (but as it is an sRGB color it should be moved to that section):

The specified value of transparent is "transparent" while the computed and used value is transparent black.

svgeesus avatar Jan 17 '23 13:01 svgeesus

Dealing with specified values in 14. Resolving <color> Values confuses me.

I would not expect a specified value to resolve. I would expect it to remain (close) to the (tokenized) value as specified by its author. I would only expect 14. Resolve <color> Values to define any transformation on the specified value to resolve the computed value, and any transformation on the computed value to resolve the used value.

In my opinion, for specified value:

  1. <system-color> or <deprecated-color> should also serialize to the lowercase color name, however I think lowercase color keywords (<named-color>, <system-color>, <deprecated-color>, transparent, currentcolor) already stems from serializing a keyword (CSSOM), therefore it is not strictly required to be defined in CSS Color
  2. mapping <percentage> to <number> should be defined in 15. Serializing <color> Values

2 is not required for specified values, but this is what browsers are currently doing. Obviously, if <percentage> should be mapped to <number> for resolved values and when serializing a specified value, it can be done at parse-time for specified values, instead of at serialization time.

Nevertheless it would be less confusing to define it in 15. Serializing <color> Values. I think there are precedents for this in other specs.

cdoublev avatar Jan 19 '23 20:01 cdoublev

I assume this issue is about serializing all color keywords instead of creating a specific issue or adding noise to #8312.

Chrome/FF serialize specified <deprecated-color> to lowercase but:

User agents must support these keywords, and to mitigate fingerprinting must map them to the (undeprecated) system colors as listed below.

ie. mapping is not applied.

14.1. Resolving sRGB values

This applies to: [...] deprecated-colors

If the sRGB color was explicitly specified by the author as a named color, or as a system color, the specified value is that named or system color, converted to ASCII lowercase. [...] Otherwise, the specified, computed and used value is the corresponding sRGB color, paired with the specified alpha channel

This section seems to define that specified <deprecated-color> must serialize to rgb().

14.5. Resolving other colors

This applies to system colors (including the <deprecated-color>s), [...]

The specified value for each <system-color> keyword is the corresponding color in its color space.

This section seems to define that specified <deprecated-color> must serialize to rgb().

15.2. Serializing sRGB values

The serialized form of the following sRGB values: [...] deprecated-colors, is derived from the specified value.

When serializing the value of a property which was set by the author to a CSS named color, therefore, for the specified value, the (all lowercase) named value is retained. [...]

For all other sRGB values, the specified, computed and used value is the corresponding sRGB value.

This section seems to define that specified <deprecated-color> must serialize to rgb().

cdoublev avatar Jan 20 '23 09:01 cdoublev

The intent is that the specified value is the ASCII-lowercased keyword and the computed value is rgb(). But thanks for noticing that

set by the author to a CSS named color,

should be expanded to

set by the author to a CSS named color, system color, deprecated system color or transparent

See also

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

svgeesus avatar Jan 20 '23 14:01 svgeesus

I would not expect a specified value to resolve. I would expect it to remain (close) to the (tokenized) value as specified by its author. I would only expect 14. Resolve Values to define any transformation on the specified value to resolve the computed value, and any transformation on the computed value to resolve the used value.

I see what you mean, will need to re-read the resolving and serializing sections again end to end to see what needs to be moved.

Meanwhile https://github.com/w3c/csswg-drafts/commit/69398afe4c10c7bfa9164c10d4a2b8b3ae2b50ef helps with some of the points you made.

svgeesus avatar Jan 20 '23 15:01 svgeesus

@GPHemsley does Serializing sRGB values look okay to you now, in terms of your original question? Specifically:

When serializing the value of a property which was set by the author to a CSS named color, a system color, a deprecated-color, or transparent therefore, for the specified value, the ASCII lowercase keyword value is retained. For the computed and used value, the corresponding sRGB value is used.

svgeesus avatar Jan 31 '23 15:01 svgeesus

The CSS Working Group just discussed [css-color-4] Serialization of named colors, and agreed to the following:

  • RESOLVED: Accept Chris's edits
The full IRC log of that discussion <chris> We got rough consensus in the issue, I made the edits, just looking for confirmation https://github.com/w3c/csswg-drafts/issues/7870#issuecomment-1410589234
<TabAtkins> chris: I think I understood the consensus and made the edits
<TabAtkins> chris: Looking for a thumbs up or mistakes
<TabAtkins> TabAtkins: I can review this asap
<TabAtkins> TabAtkins: but we can resolve now
<TabAtkins> astearns: so proposed reoslution is to adopt the changes added in response to this issue
<TabAtkins> RESOLVED: Accept Chris's edits
<chris> q+

css-meeting-bot avatar Feb 08 '23 17:02 css-meeting-bot