You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-color] Clarification needed on how missing alpha components flow through relative color syntax for hsl/hwb #10254
If the alpha value of the relative color is omitted, it defaults to that of the origin color (rather than defaulting to 100%, as it does in the absolute syntax).
To restate what is probably obvious though, the bigger issue on this one is should the conversion from HSL()/HWB() to color(srgb) done for serialization be a "normal conversion" or should it be a "conversion that carries forward analogous component missing values"?
I thought a bit more about this and I think preserving the NaN (that is, using the "carries forward analogous component missing values" conversion) for alpha is better than not.
My argument is there really isn't any value in converting it to 0 here. As much as possible, serialization tries to preserve as much information as possible, and since we can preserve this, why not. (It also seems to be what Chrome does).
One things this does is beg the question, should all conversions between color spaces carry forward analogous missing components? In what cases would it not be what you want?
Is there any part of the specification that indicates that you shouldn't always carry forward analogous missing components during conversions between color spaces?
Is there any part of the specification that indicates that you shouldn't always carry forward analogous missing components during conversions between color spaces?
I thought this was always required.
Section 4.4 is pretty explicit.
For all other purposes, a missing component behaves as a zero value, in the appropriate unit for that component: 0, 0%, or 0deg. This includes rendering the color directly, converting it to another color space, performing computations on the color component values, etc.
And since interpolation calls it out as a separate step, I think the implication is that if an algorithm wants carrying forward, it needs to call it out.
The intention is to preserve missing components / none as much as possible.
So if there are algorithms where it isn't stated and where it could be preserved, then we should change that.
The serialization as color(srgb) for specific cases is problematic when trying to preserve missing components / none.
It doesn't currently state that carry forward should happen. But it also makes carry forward impossible for non-alpha components when the src and dest aren't both in srgb to begin with.
This would also affect interpolation but there isn't any interop for none alpha.
Chrome threats none in alpha during interpolation as the alpha of the other color. Safari and Firefox do not.
The CSS Working Group just discussed [css-color] Clarification needed on how missing alpha components flow through relative color syntax for hsl/hwb, and agreed to the following:
RESOLVED: if 'none' is used in hsl and hwb, we serialize with slashes and none; and for rgb, we serialize with color function
The full IRC log of that discussion
<ChrisL> q+
<astearns> ack ChrisL
<dholbert> ChrisL: rgb and hsl serialize as legacy syntax, for compat/historical reasons
<weinig> q+
<dholbert> ChrisL: so they can't use the word 'none'
<dholbert> ChrisL: people have suggested that they serialize with modern syntax which does include 'none'
<astearns> ack weinig
<dholbert> ChrisL: let's resolve on that
<dholbert> weinig: in webkit we implement something a bit different
<dholbert> weinig: we serialize as hsl, and none is preserved, if you happen to use 'none'
<dholbert> weinig: so we pull legacy colors out of legacy prison if they happen to use 'none'
<TabAtkins> +1 to this
<dholbert> weinig: if you're using modern keywords, then they're not legacy colors anymore, so we're not bound by compatibility
<TabAtkins> that's def where i thought Chris was gonna go, i was surprised by the color() swerve
<dholbert> weinig: so if you use none in rgb, we should serialize them as-is
<romain> present-
<dholbert> ChrisL/ weinig : if we did conversion to srgb, all the nones would have to be resolved to 0
<dholbert> ChrisL: I like what weinig said better than my proposal
<dholbert> ChrisL: proposal is to serialize with modern syntax, with the slashes
<dholbert> emilio: I think it would be preferable to serialize with color() to avoid introducing a third format that authors need to deal with
<dholbert> ChrisL: the advantage is if you have a 'none' hue, then you can preserve that
<dholbert> ChrisL: whereas if you serialize to srgb, you have to convert it to 0
<dholbert> weinig: another reason this is straightforward: to make interpolation between hsl()'s work well... once you have 'none' in them, we internally keep them as hsl all the way through
<dholbert> so it doesn't affect the optimizations that engines have where hsls without none can be converted to 32-bit int
<dholbert> emilio: I guess the alternative would be to add a color-hsl() sort of thing...
<dholbert> ChrisL: I don't really like that
<dholbert> emilio: vs. legacy hsl... that might be more consistent?
<dholbert> ChrisL: it'd be modeled after hwb maybe
<dholbert> weinig: I don't think that's true; I think hwb follows the hsl pattern
<dholbert> weinig: we've been shipping this in webkit
<dholbert> emilio: I agree we need a new serialization either way. Either you convert to rgb, or... Also, for colors that do have the color() function, if you specify 'none' in rgb, we have to decide whether to serialize with slashes or not
<dholbert> ChrisL: my point from hwb is that it *only* uses slash syntax
<dholbert> emilio: but it only serializes as rgb, so engines convert it
<dholbert> emilio: my only concern with doing what's proposed is that there's a lot of parsing on the web that assumes rgb will serialize with commas
<dholbert> emilio: but on the other hand this scenario is an edge case and so pages probably wouldn't trip over this accidentally
<dholbert> emilio: but authors need to be prepared to parse a third syntax
<dholbert> emilio: this is a weak argument... I'm fine
<dholbert> weinig: authors have to handle a lot of other syntaxes as well, yeah
<dholbert> emilio: I'm fine with what weinig proposed
<dholbert> emilio: it's effectively the same as serializing with color and adding a color-hsl thing; it's about the same amount of work
<dholbert> emilio: it's weird that some colors cannot be specified with color(), but that ship has sailed
<dholbert> astearns: so hsl, rgb, and hwb colors... if 'none' is used, then we serialize the color as-specified?
<dholbert> ChrisL: we serialize using a modern syntax which does not yet exist, with hsl(...) with slashes and allows the word 'none'
<dholbert> emilio: the other weird thing is that for rgb, that would introduce 3 syntaxes when we can get away with 2
<dholbert> ChrisL: do we need it for rgb?
<dholbert> emilio: yeah, to preserve 'none'
<dholbert> emilio: in gecko, if you specify 'none' in alpha for rgb, we serialize with 0
<dholbert> and commas
<emilio> rgb(100 100 0 / none) -> color(srgb, ...)
<emilio> hsl(100 100 0 / none) -> hsl(100 100 0 / none)
<dholbert> emilio: so we should serialize like that^ ?
<dholbert> ChrisL: yes
<dholbert> emilio: I think that's fine
<ChrisL> and hsl(none 100 0) similarly preserves none
<dholbert> astearns: proposed resolution: if none is used, we serialize like that
<ChrisL> q+
<dholbert> emilio: does webkit do this?
<astearns> ack ChrisL
<dholbert> weinig: I'll check
<dholbert> ChrisL: authors can use this syntax too, right?
<dholbert> emilio: yeah
<dholbert> weinig: this round-trips, yeah. that's the most important property to preserve
<dholbert> PROPOSED: if 'none' is used in colors, we serialize with slashes and none
<dholbert> PROPOSED: if 'none' is used in hsl and hwb, we serialize with slashes and none; and for rgb, we serialize with color function
<TabAtkins> I don't know why we're doing this, but I don't care.
<dholbert> emilio: alternatively we could add color-hsl
<dholbert> weinig: but then color-oklab, etc
<emilio> s/color-hsl/color(hsl, ...)
<dholbert> RESOLVED: if 'none' is used in hsl and hwb, we serialize with slashes and none; and for rgb, we serialize with color function
<dholbert> weinig: this isn't specific to 'alpha', right?
<dholbert> ChrisL, emilio : right
<dholbert> astearns: done with morning session. lunch time
It occurred to me after the discussion that the proposal is very close (if not identical) to what we have for relative color syntax origin color serialization (https://drafts.csswg.org/css-color-5/#serial-origin-color), including preserving hsl()/hwb(). Re-using some of that language will probably make specifying this easier.
Activity
svgeesus commentedon Apr 26, 2024
I think this is from 4.1. Processing Model for Relative Colors :
Aha! It is implied, but not directly stated, that alpha is analogous to alpha.
svgeesus commentedon Apr 26, 2024
If you agree, then I can add alpha to 12.2. Interpolating with Missing Components
svgeesus commentedon Apr 26, 2024
I'm not fully sure on that point.
weinig commentedon Apr 27, 2024
I totally agree that adding something to 12.2. Interpolating with Missing Components that says alpha is analogous to alpha would be great.
To restate what is probably obvious though, the bigger issue on this one is should the conversion from HSL()/HWB() to color(srgb) done for serialization be a "normal conversion" or should it be a "conversion that carries forward analogous component missing values"?
weinig commentedon Apr 27, 2024
I thought a bit more about this and I think preserving the NaN (that is, using the "carries forward analogous component missing values" conversion) for alpha is better than not.
My argument is there really isn't any value in converting it to 0 here. As much as possible, serialization tries to preserve as much information as possible, and since we can preserve this, why not. (It also seems to be what Chrome does).
One things this does is beg the question, should all conversions between color spaces carry forward analogous missing components? In what cases would it not be what you want?
romainmenke commentedon Apr 27, 2024
Is there any part of the specification that indicates that you shouldn't always carry forward analogous missing components during conversions between color spaces?
I thought this was always required.
weinig commentedon Apr 27, 2024
Section 4.4 is pretty explicit.
https://www.w3.org/TR/css-color-4/#missing
weinig commentedon Apr 27, 2024
And since interpolation calls it out as a separate step, I think the implication is that if an algorithm wants carrying forward, it needs to call it out.
romainmenke commentedon Apr 28, 2024
Ah, indeed!
The intention is to preserve missing components /
noneas much as possible.So if there are algorithms where it isn't stated and where it could be preserved, then we should change that.
The serialization as
color(srgb)for specific cases is problematic when trying to preserve missing components /none.It doesn't currently state that carry forward should happen. But it also makes carry forward impossible for non-alpha components when the src and dest aren't both in srgb to begin with.
romainmenke commentedon Apr 28, 2024
https://codepen.io/romainmenke/pen/LYvvNrb
This would also affect interpolation but there isn't any interop for
nonealpha.Chrome threats
nonein alpha during interpolation as the alpha of the other color. Safari and Firefox do not.19 remaining items
svgeesus commentedon Jan 27, 2026
This affects
rgb(),hsl()because currently these serialize in legacy syntax "for historical reasons". Should also affecthwb()css-meeting-bot commentedon Jan 27, 2026
The CSS Working Group just discussed
[css-color] Clarification needed on how missing alpha components flow through relative color syntax for hsl/hwb, and agreed to the following:RESOLVED: if 'none' is used in hsl and hwb, we serialize with slashes and none; and for rgb, we serialize with color functionThe full IRC log of that discussion
<ChrisL> q+<astearns> ack ChrisL
<dholbert> ChrisL: rgb and hsl serialize as legacy syntax, for compat/historical reasons
<weinig> q+
<dholbert> ChrisL: so they can't use the word 'none'
<dholbert> ChrisL: people have suggested that they serialize with modern syntax which does include 'none'
<astearns> ack weinig
<dholbert> ChrisL: let's resolve on that
<dholbert> weinig: in webkit we implement something a bit different
<dholbert> weinig: we serialize as hsl, and none is preserved, if you happen to use 'none'
<dholbert> weinig: so we pull legacy colors out of legacy prison if they happen to use 'none'
<TabAtkins> +1 to this
<dholbert> weinig: if you're using modern keywords, then they're not legacy colors anymore, so we're not bound by compatibility
<TabAtkins> that's def where i thought Chris was gonna go, i was surprised by the color() swerve
<dholbert> weinig: so if you use none in rgb, we should serialize them as-is
<romain> present-
<dholbert> ChrisL/ weinig : if we did conversion to srgb, all the nones would have to be resolved to 0
<dholbert> ChrisL: I like what weinig said better than my proposal
<dholbert> ChrisL: proposal is to serialize with modern syntax, with the slashes
<dholbert> emilio: I think it would be preferable to serialize with color() to avoid introducing a third format that authors need to deal with
<dholbert> ChrisL: the advantage is if you have a 'none' hue, then you can preserve that
<dholbert> ChrisL: whereas if you serialize to srgb, you have to convert it to 0
<dholbert> weinig: another reason this is straightforward: to make interpolation between hsl()'s work well... once you have 'none' in them, we internally keep them as hsl all the way through
<dholbert> so it doesn't affect the optimizations that engines have where hsls without none can be converted to 32-bit int
<dholbert> emilio: I guess the alternative would be to add a color-hsl() sort of thing...
<dholbert> ChrisL: I don't really like that
<dholbert> emilio: vs. legacy hsl... that might be more consistent?
<dholbert> ChrisL: it'd be modeled after hwb maybe
<dholbert> weinig: I don't think that's true; I think hwb follows the hsl pattern
<dholbert> weinig: we've been shipping this in webkit
<dholbert> emilio: I agree we need a new serialization either way. Either you convert to rgb, or... Also, for colors that do have the color() function, if you specify 'none' in rgb, we have to decide whether to serialize with slashes or not
<dholbert> ChrisL: my point from hwb is that it *only* uses slash syntax
<dholbert> emilio: but it only serializes as rgb, so engines convert it
<dholbert> emilio: my only concern with doing what's proposed is that there's a lot of parsing on the web that assumes rgb will serialize with commas
<dholbert> emilio: but on the other hand this scenario is an edge case and so pages probably wouldn't trip over this accidentally
<dholbert> emilio: but authors need to be prepared to parse a third syntax
<dholbert> emilio: this is a weak argument... I'm fine
<dholbert> weinig: authors have to handle a lot of other syntaxes as well, yeah
<dholbert> emilio: I'm fine with what weinig proposed
<dholbert> emilio: it's effectively the same as serializing with color and adding a color-hsl thing; it's about the same amount of work
<dholbert> emilio: it's weird that some colors cannot be specified with color(), but that ship has sailed
<dholbert> astearns: so hsl, rgb, and hwb colors... if 'none' is used, then we serialize the color as-specified?
<dholbert> ChrisL: we serialize using a modern syntax which does not yet exist, with hsl(...) with slashes and allows the word 'none'
<dholbert> emilio: the other weird thing is that for rgb, that would introduce 3 syntaxes when we can get away with 2
<dholbert> ChrisL: do we need it for rgb?
<dholbert> emilio: yeah, to preserve 'none'
<dholbert> emilio: in gecko, if you specify 'none' in alpha for rgb, we serialize with 0
<dholbert> and commas
<emilio> rgb(100 100 0 / none) -> color(srgb, ...)
<emilio> hsl(100 100 0 / none) -> hsl(100 100 0 / none)
<dholbert> emilio: so we should serialize like that^ ?
<dholbert> ChrisL: yes
<dholbert> emilio: I think that's fine
<ChrisL> and hsl(none 100 0) similarly preserves none
<dholbert> astearns: proposed resolution: if none is used, we serialize like that
<ChrisL> q+
<dholbert> emilio: does webkit do this?
<astearns> ack ChrisL
<dholbert> weinig: I'll check
<dholbert> ChrisL: authors can use this syntax too, right?
<dholbert> emilio: yeah
<dholbert> weinig: this round-trips, yeah. that's the most important property to preserve
<dholbert> PROPOSED: if 'none' is used in colors, we serialize with slashes and none
<dholbert> PROPOSED: if 'none' is used in hsl and hwb, we serialize with slashes and none; and for rgb, we serialize with color function
<TabAtkins> I don't know why we're doing this, but I don't care.
<dholbert> emilio: alternatively we could add color-hsl
<dholbert> weinig: but then color-oklab, etc
<emilio> s/color-hsl/color(hsl, ...)
<dholbert> RESOLVED: if 'none' is used in hsl and hwb, we serialize with slashes and none; and for rgb, we serialize with color function
<dholbert> weinig: this isn't specific to 'alpha', right?
<dholbert> ChrisL, emilio : right
<dholbert> astearns: done with morning session. lunch time
weinig commentedon Jan 28, 2026
It occurred to me after the discussion that the proposal is very close (if not identical) to what we have for relative color syntax origin color serialization (https://drafts.csswg.org/css-color-5/#serial-origin-color), including preserving hsl()/hwb(). Re-using some of that language will probably make specifying this easier.
[css-color-4] Pick sRGB serialization form by presence of none, #10254
[css-color-5] Preserve hsl/hwb identity when result contains none, #1…
cdoublev commentedon May 3, 2026
Based on the last changes, I do not know how
rgb(from red 0 none 0)should serialize as a component of a declared value.romainmenke commentedon Oct 24, 2026
I think we now have sufficient test coverage for this issue through https://github.com/web-platform-tests/wpt/blob/b6bb7b1108e604b3b2cc29329bc8ceae9fd48109/css/css-color/parsing/color-computed-none.html
I've added a few more in: web-platform-tests/wpt#64150, just to be sure.