Skip to content

Commit ec017b3

Browse files
svgeesusclaude
andcommitted
[css-color-4] Pick sRGB serialization form by presence of none, w3c#10254
Per CSSWG resolution 2026-01-27: when an sRGB-family value has at least one missing component, the legacy comma form cannot represent none. Define the serialization form by the declared color function instead: - rgb()/rgba() with none => color(srgb r g b / a) - hsl()/hsla() with none => modern hsl(H S L / A) - hwb() with none => modern hwb(H W B / A) Also call out in §12.2 that alpha is its own analogous component (so a missing alpha is carried forward like any other missing component), and promote the missing-component dfn aliases ("missing", "missing component") from local-lt to exported lt so cross-spec links from css-color-5 resolve. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 12949a1 commit ec017b3

1 file changed

Lines changed: 120 additions & 4 deletions

File tree

css-color-4/Overview.bs

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ will have a [=powerless=] hue component.
11581158

11591159
In certain cases,
11601160
a color can have one or more
1161-
<dfn export lt="missing color component" local-lt="missing|missing component">missing color components</dfn>.
1161+
<dfn export lt="missing color component | missing | missing component">missing color components</dfn>.
11621162

11631163
In this specification,
11641164
this happens automatically due to [[#hue-interpolation|hue-based interpolation]]
@@ -5088,6 +5088,12 @@ Interpolating with Missing Components</h3>
50885088
in the corresponding [=analogous set=]
50895089
of the [=interpolation color space=].
50905090

5091+
Alpha is its own analogous component
5092+
(alpha is analogous to alpha),
5093+
so a [=missing component|missing=] alpha
5094+
is [=carried forward=] in exactly the same way
5095+
as any other [=missing component=].
5096+
50915097
The <dfn export>analogous components</dfn> are as follows:
50925098

50935099
<table>
@@ -6969,7 +6975,18 @@ Serializing sRGB values</h3>
69696975

69706976
During serialization,
69716977
any [=missing=] values
6972-
are converted to 0.
6978+
are converted to 0
6979+
if the chosen serialization form
6980+
(such as the <a>legacy color syntax</a> with comma separators,
6981+
or the
6982+
<a href="#HTML-compatible-serialization-of-srgb">HTML-compatible serialization</a>
6983+
of sRGB values)
6984+
cannot represent the ''none'' keyword.
6985+
When at least one component is [=missing=]
6986+
and the value can be serialized in a form which supports ''none'',
6987+
the form is chosen as described in
6988+
[[#css-serialization-of-srgb]]
6989+
so that [=missing color components=] are preserved as ''none''.
69736990

69746991
<h4 id="HTML-compatible-serialization-of-srgb">HTML-compatible serialization of sRGB values</h4>
69756992

@@ -7040,7 +7057,8 @@ Serializing sRGB values</h3>
70407057

70417058
<h4 id="css-serialization-of-srgb">CSS serialization of sRGB values</h4>
70427059

7043-
Corresponding sRGB values use either the ''rgb()'' or ''rgba()'' form
7060+
If the value has no [=missing color components=],
7061+
corresponding sRGB values use either the ''rgb()'' or ''rgba()'' form
70447062
(depending on whether the (clamped) alpha is exactly 1, or not),
70457063
with all <a href="https://infra.spec.whatwg.org/#ascii-lowercase">ASCII lowercase</a>
70467064
letters for the function name.
@@ -7067,7 +7085,77 @@ Serializing sRGB values</h3>
70677085
to separate the blue component of ''rgba()''
70687086
from the alpha value.
70697087

7070-
7088+
However, the <a>legacy color syntax</a> with comma separators
7089+
cannot represent ''none''.
7090+
If the value has at least one [=missing color component=],
7091+
the serialization form is chosen
7092+
to preserve those components as the ''none'' keyword,
7093+
based on the color function of the [=declared value=]:
7094+
7095+
* For ''rgb()'' and ''rgba()'' values
7096+
(the only sRGB form in this list whose syntax accepts ''none'';
7097+
[=hex colors=], [=named colors=], [=system colors=],
7098+
<a href="#deprecated-system-colors">deprecated-colors</a>,
7099+
and ''transparent'' have no parametric syntax
7100+
and so never have [=missing color components=]),
7101+
the value is serialized as a ''color()'' function
7102+
in the ''srgb'' [=color space=]
7103+
rather than as the modern space-separated form of ''rgb()'',
7104+
even though that form would also accept ''none'':
7105+
"color(srgb"
7106+
followed by a single space,
7107+
followed by a space-separated list of the three
7108+
non-alpha components serialized as <<number>>s
7109+
in the [0, 1] reference range
7110+
(or as ''none'' if [=missing=]),
7111+
followed (only if the alpha is non-unity or [=missing=])
7112+
by " / "
7113+
and the alpha component
7114+
(serialized per the
7115+
<a href="#serializing-alpha-values">alpha rules</a>,
7116+
or as ''none'' if [=missing=]),
7117+
followed by ")".
7118+
7119+
* For ''hsl()'' and ''hsla()'' values,
7120+
the value is serialized using the
7121+
modern (whitespace-separated) ''hsl()'' syntax,
7122+
with a slash before the alpha component when present.
7123+
The function name is "hsl" (in
7124+
<a href="https://infra.spec.whatwg.org/#ascii-lowercase">ASCII lowercase</a>)
7125+
regardless of whether the value was authored
7126+
using the ''hsla()'' alias.
7127+
The hue is serialized as a canonicalized <<number>> in degrees,
7128+
the saturation and lightness as <<percentage>>s,
7129+
and the alpha
7130+
(included only if non-unity or [=missing=])
7131+
per the <a href="#serializing-alpha-values">alpha rules</a>;
7132+
any [=missing component=] is serialized as the ''none'' keyword.
7133+
7134+
* For ''hwb()'' values,
7135+
the value is serialized using the
7136+
modern (whitespace-separated) ''hwb()'' syntax,
7137+
with a slash before the alpha component when present.
7138+
The function name is "hwb"
7139+
in <a href="https://infra.spec.whatwg.org/#ascii-lowercase">ASCII lowercase</a>.
7140+
The hue is serialized as a canonicalized <<number>> in degrees,
7141+
the whiteness and blackness as <<percentage>>s,
7142+
and the alpha
7143+
(included only if non-unity or [=missing=])
7144+
per the <a href="#serializing-alpha-values">alpha rules</a>;
7145+
any [=missing component=] is serialized as the ''none'' keyword.
7146+
7147+
Note: this means that an ''hsl()'' or ''hwb()'' value
7148+
containing ''none'' round-trips through serialization
7149+
in its own color function,
7150+
rather than degrading to ''rgba()'' (whose legacy form cannot represent ''none''),
7151+
while an ''rgb()'' value containing ''none''
7152+
is serialized via ''color(srgb …)''.
7153+
The modern space-separated form of ''rgb()'' could itself represent ''none'',
7154+
but the [[#serializing-color-values|sRGB CSS serialization]] uses ''color(srgb …)'' instead
7155+
for consistency with how all other [=color spaces=] are serialized
7156+
in their non-legacy form.
7157+
This parallels the behavior of relative color syntax
7158+
defined in [[css-color-5#serial-origin-color]].
70717159

70727160
<div class="example" id="ex-rgb-ser-int-rgba">
70737161
<p>For example, the serialized value of</p>
@@ -7099,6 +7187,34 @@ Serializing sRGB values</h3>
70997187

71007188
</div>
71017189

7190+
<div class="example" id="ex-hwb-serial-none">
7191+
For example, the author-supplied value
7192+
7193+
<pre class="lang-css">hwb(20 none 30% / none)</pre>
7194+
7195+
contains [=missing color components=]
7196+
(both the whiteness and the alpha are ''none''),
7197+
so it is <em>not</em> serialized through ''rgba()''.
7198+
Instead, it is serialized using the modern ''hwb()'' syntax as
7199+
7200+
<pre class="lang-css">hwb(20 none 30% / none)</pre>
7201+
7202+
preserving each ''none'' value.
7203+
</div>
7204+
7205+
<div class="example" id="ex-rgb-serial-none">
7206+
Similarly, the author-supplied value
7207+
7208+
<pre class="lang-css">rgb(none 0 0)</pre>
7209+
7210+
is serialized as
7211+
7212+
<pre class="lang-css">color(srgb none 0 0)</pre>
7213+
7214+
because ''rgb()'' (in its serialized legacy comma form)
7215+
cannot represent ''none''.
7216+
</div>
7217+
71027218
Note: contrary to CSS Color 3,
71037219
the parameters of the ''rgb()'' function
71047220
are of type <<number>>, not <<integer>>.

0 commit comments

Comments
 (0)