- From: Guillaume via GitHub <sysbot+gh@w3.org>
- Date: Sat, 15 Jun 2024 11:57:57 +0000
- To: public-css-archive@w3.org
[Converting HWB to sRGB](https://drafts.csswg.org/css-color-4/#hwb-to-rgb) produces `NaN` when whiteness is `-Infinity` or `+Infinity` (produced by a math function) or blackness is `-Infinity`. For example, the current version of Chrome (126) serializes `rgb(NaN, NaN, NaN)` from `hwb(0 calc(-infinity) 0)`. FF clamps whiteness and blackness before the conversion. Serializing `hwb()` requires converting to `rgb()`, therefore resolving math functions (extracting their result) before, as noted in [14.1. Resolving sRGB values](https://drafts.csswg.org/css-color-4/#resolving-sRGB-values): > For historical reasons, when `calc()` in sRGB colors resolves to a single value, the declared value serialises without the "calc(" ")" wrapper. **Note:** `calc()` should be replaced with *a math function*. CSS Color 4 then says: > Also for historical reasons, when `calc()` is simplified down to a single value, the color values are clamped to `[0.0, 255.0]`. But it does not require clamping `hwb()` channel values before conversion to `rgb()`. I do not think `NaN` cases can be specifically handled in the conversion algorithm. When whiteness/blackness is < 0 or > 100, the produced color is different depending on which of whiteness/blackness (line in FF) or RGB (like in Chrome) values are clamped: ```js // whiteness < 0 $el1.style.color = 'hwb(90 -200 0)' $el2.style.color = 'hwb(90 -100 0)' $el3.style.color = 'hwb(90 -50 0)' $el4.style.color = 'hwb(90 0 0)' getComputedStyle($el1).color; // rgb(128, 255, 0) in FF, rgb(0, 255, 0) in Chrome getComputedStyle($el2).color; // rgb(128, 255, 0) in FF, rgb(0, 255, 0) in Chrome getComputedStyle($el3).color; // rgb(128, 255, 0) in FF, rgb(64, 255, 0) in Chrome getComputedStyle($el4).color; // rgb(128, 255, 0) in FF and Chrome // whiteness > 100 $el5.style.color = 'hwb(0 100 50)' $el6.style.color = 'hwb(0 200 50)' getComputedStyle($el5).color; // rgb(170, 170, 170) in FF and Chrome getComputedStyle($el6).color; // rgb(170, 170, 170) in FF, rgb(204, 204, 204) in Chrome ``` When whiteness/blackness is < 0 and not clamped, the hue is shifted: `hwb(90 -100 0)` becomes `hwb(120 0 0)`. When whiteness/blackness is > 100 and not clamped, the lightness is shifted: `hwb(0 200 50)` becomes `hwb(0 100 25)`. Finally, when `(whiteness + blackness) > 1`, I am not sure I understand the current logic. If the algorithm should match the result of mixing paints, I do not understand why the produced color is not white when `(whiteness - blackness) > 100`, or black when `(blackness - whiteness) > 100`. `whiteness + blackness` should probably not be greater than `100`. --- I am not sure I understand the reasons, the conditions, the timing, for clamping out of range values. HSL is off topic but similar observations can be made: - when saturation is > 100 and lightness < 0, eg. `hsl(0 200 -25)`, the hue and lightness are shifted: I would expect black, but I get `rgb(0, 64, 64)` in Chrome - when saturation is > 100 and 0 < lightness < 100, eg. `hsl(90 200 25)`, the hue and lightness are shifted: I get `rgb(64, 191, 0)` in Chrome, which corresponds to `hsl(100 100 37.45)` Currently, channel values that must be clamped are: - RGB - saturation at lower boundary - chromaticity at lower boundary - lightness of `ok?lab()` and `ok?lch()` They must be clamped at parse time. They must not be clamped in a relative or origin color (and possibly in `color-mix()`, #10414). For RGB, CSS Color 3 optionally requires gamut mapping, without defining how or when. CSS Color 4 required clamping at computed value time before. For saturation, CSS Color 4 follows CSS Color 3, which requires clamping, without defining when, and lets UAs optionally gamut mapping other channel values (like RGB). CSS Color 4 required clamping saturation and lightness at computed value time before. For chromaticity and lightness of `ok?lab()` and `ok?lch()`, CSS Color 4 required clamping at computed value time before. If the reason for clamping RGB and saturation is backward compatibility, what are the reasons for clamping chromaticity and lightness of `ok?lab()` and `ok?lch()`? -- GitHub Notification of comment by cdoublev Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10368#issuecomment-2169392747 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Saturday, 15 June 2024 11:57:58 UTC