Open weinig opened 4 months ago
The spec goes on to state:
The serialization of the result of a relative color function depends on whether the keyword currentColor is the origin color. If so, the result is serialized as the declared value. This allows the correct value to be used on child elements whose color property has a different value. Otherwise, it is the resolved value, which is a
<color>
, as defined in CSS Color 4 § 15. Serializing<color>
Values.
I understand this to mean:
currentColor
, then serialize the spelling as declared. (We don't know the origin color and thus cannot canonicalize it.)currentColor
, then resolve the relative color and serialize canonically as described in Color 4.There are few tests with examples for how canonicalization happens in case 2: color-valid.html, color-valid-rgb.html, color-valid-hsl.html. Notably:
hsla(...)
canonicalizes to equivalent rgba(...)
, and hsl(...)
canonicalizes to equivalent rgb(...)
rgb(...)
is used if the clamped alpha is exactly 1, otherwise rgba(...)
is usedcc @svgeesus to confirm.
I filed a separate issue on the ambiguity here - https://github.com/w3c/csswg-drafts/issues/10305, as I don't think the current spec text is clear on what the rules are.
Regardless of that however, the question posed here remains, as you can just set currentColor as the origin:
That is, should:
rgb(from currentcolor r g b)
and
rgba(from currentcolor r g b)
serializations maintain the exact spelling of function name.
@kbabbitt, the tests you mention, notably, cover the absolute case, which has clear rules about which spelling to do, and those rules are not about what spelling was used at the declaration site, but rather about the resolved value of the alpha channel. As you might not know the value of the alpha channel in a relative color, the exact same rules can't be followed.
cc @LeaVerou
Fwiw, I would prefer to avoid omitting alpha >= 1 and canonicalizing (edit: never mind, I have no preference), but I do not know the "historical reasons" why browsers need to resolve them when serializing them as components of declared values.rgba?()
and hsla?()
depending on whether it is omitted
I don’t think the historical concerns apply to the relative form as there is no existing use to worry about breaking.
Yup, I think it's fine to do whatever is reasonable in this case, since the historical concerns don’t apply.
My preference here would be to serialize:
rgb(from ...)
and rgba(from ...)
as rgb(from ...)
hsl(from ...)
and hsla(from ...)
as hsl(from ...)
This loses no useful information, and is minimal, which generally CSS serialization tries to achieve.
It's not a huge deal, implementation wise, to preserve the specific spelling for serialization, so whatever is decided here is fine.
That makes sense. Agenda+ so we can resolve.
My preference here would be to serialize:
rgb(from ...)
andrgba(from ...)
asrgb(from ...)
hsl(from ...)
andhsla(from ...)
ashsl(from ...)
I agree this makes the most sense, and would be happy with that resolution.
proposed resolutions:
The CSS Working Group just discussed [css-color-5] Should relative `rgb()`/`rgba()` and relative `hsl()`/`hsla()` serialize exactly as declared?
, and agreed to the following:
RESOLVED: relative rgb()/rgba() and relative hsl()/hsla() serialize as rgb() and hsl() when alpha is unity.
RESOLVED: relative rgb()/rgba() and relative hsl()/hsla() serialize as rgb() and hsl() when alpha is unity or unknown (like with currentColor)
Agenda+ to clarify the intent of the WG in the resolution taken previously.
The question originally posed was, by my read, a narrow matter of: when a relative color is serialized as rgb()
/rgba()
or hsl()
/hsla()
, whether the form without the a
should be used.
Currently, per spec, the above only happens when a relative color is based on currentcolor
. For relative colors that are resolvable at parse time, they serialize as their resolved form. And per the same spec section, the resolved form serializes as color(srgb ...)
since the mixing color space was srgb or hsl. Blink and Gecko have both shipped this behavior.
Some WPT changes landed recently that appear to interpret the resolution more broadly: that relative colors declared in rgb()
/rgba()
/hsl()
/hsla()
should serialize in their declared forms rather than their resolved forms. In fact, the WPT changes go one step further and assert that relative colors declared with other functions such as lab()
or lch()
should also serialize in their declared forms rather than resolved forms. (See color-valid-relative-color.html in the linked commit.)
Unfortunately, I did not realize that 'should' implication at the time we took the resolution, nor did I realize that it would constitute a break from shipped behavior. :|
The question of whether to serialize in declared or resolved form is asked more directly in #10305, which the WG has not resolved on. Because that would be a breaking change, it's not clear to me we can make it absent compat analysis. I'm happy to do that analysis; however these changes also impact Interop2024, and the remaining runway for that is short. I can't promise I'd be able to get good enough data for the WG to resolve and implementations to adopt the change by the end of the year.
How does the rest of the WG understand the question and resolution here vs 10305?
cc @emilio
@kbabbitt, I think the WPT changes are in line with the changes from https://github.com/w3c/csswg-drafts/issues/10328, where I wrote out a more thorough definition for the serialization of relative colors.
@weinig Thanks for the pointer, that issue does cover it, not sure how I missed it. Will take up further discussion there.
In CSS Color 5, the serialization of relative colors is defined with the following:
Does this mean that when serializing
rgb(from ...)
/rgba(from ...)
that the specific spelling as declared,rgb
vsrgba
should be preserved? Or is ok to canonicalize to one or the other?Similarly, for
hsl(from ...)
/hsla(from ...)
that the specific spelling as declared,hsl
vshsla
should be preserved? Or is ok to canonicalize to one or the other?