Skip to content

[css-color-5] clipping of component values in RCS #9259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
romainmenke opened this issue Aug 29, 2023 · 2 comments
Closed

[css-color-5] clipping of component values in RCS #9259

romainmenke opened this issue Aug 29, 2023 · 2 comments
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. css-color-5 Color modification

Comments

@romainmenke
Copy link
Member

romainmenke commented Aug 29, 2023

In #8444 it was resolved to allow out of gamut colors for rgb, hsl and hwb and to let them round trip as color(...) functions.

This surfaced some things which I now think are just bugs in our implementation.

When parsing any color we clip specific components.

hsl(50deg -10% 50%) is clipped to 0% saturation.

https://www.w3.org/TR/css-color-3/#hsl-color

If saturation is less than 0%, implementations must clip it to 0%. If the resulting value is outside the device gamut, implementations must clip it to the device gamut. This clipping should preserve the hue when possible, but is otherwise undefined. (In other words, the clipping is different from applying the rules for clipping of RGB colors after applying the algorithm below for converting HSL to RGB.)

But these steps are parsed-value time and we also do these steps for RCS when computing the values for specific channel keywords. I think that is obviously incorrect and we should fix this.


However I was wondering if there are now also other ways users can force rgb, hsl and hwb to produce colors that are outside the rgb gamut?

For example : color: hsl(from white 311.21deg -5.5486% 1.0906%);

This can be trivially clipped at parsed-value time, but is it really different from hsl(from lab(0 104.3 -50.9) h s l) ?


Some variants :

.foo {
  /* regular HSL, must be clipped for web compat */
  color: hsl(311.21deg -5.5486% 1.0906%);
}

.foo {
  /* calc */
  color: hsl(311.21deg calc(-5.5486%) 1.0906%);
}

.foo {
  /* var */
  --foo: -5.5486%;
  color: hsl(311.21deg var(--foo) 1.0906%);
}

.foo {
  /* RCS : 1 */
  color: hsl(from lab(0 104.3 -50.9) h s l);
}

.foo {
  /* RCS : 2 */
  color: hsl(from lab(0 104.3 -50.9) h calc(s) l);
}

.foo {
  /* RCS : 3 */
  color: hsl(from lab(0 104.3 -50.9) 311.21deg -5.5486% 1.0906%);
}

.foo {
  /* RCS : 4, same as 3, but more obvious */
  color: hsl(from white 311.21deg -5.5486% 1.0906%);
}

.foo {
  /* RCS : 5 */
  color: hsl(from white 311.21deg calc(-5.5486%) 1.0906%);
}

.foo {
  /* RCS : 6 */
  color: hsl(from white 311.21deg calc(s - 5.5486) 1.0906%);
}

.foo {
  /* RCS : 7 */
  --foo: -5.5486%;
  color: hsl(from white 311.21deg var(--foo) 1.0906%);
}
@svgeesus
Copy link
Contributor

When parsing any color we clip specific components.

hsl(50deg -10% 50%) is clipped to 0% saturation.

https://www.w3.org/TR/css-color-3/#hsl-color

Why are you citing CSS Color 3, which was restricted to the sRGB gamut? The current definition of HSL is in CSS Color 4, which has no clipping on HSL values. RCS of HSL is in CSS Color 5 and again has no clipping (but does have hue angle normalization).

@romainmenke
Copy link
Member Author

I was citing CSS Color 3 because this was the reference I could find.
I should have stated this.

I found the correct reference in the older version of css-color-4 : https://www.w3.org/TR/css-color-4/#the-hsl-notation

The next two arguments are the saturation and lightness, respectively. For saturation, 100% is a fully-saturated, bright color, and 0% is a fully-unsaturated gray. For lightness, 50% represents the "normal" color, while 100% is white and 0% is black. If the saturation or lightness are less than 0% or greater than 100%, they are clamped to those values at computed value time, before being converted to an sRGB color.

This has since changed to :

The next two arguments are the saturation and lightness, respectively. For saturation, 100% is a fully-saturated, bright color, and 0% is a fully-unsaturated gray. For lightness, 50% represents the "normal" color, while 100% is white and 0% is black.


I missed this change, sorry about the confusion here.

@svgeesus svgeesus added the Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. label Aug 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. css-color-5 Color modification
Projects
None yet
Development

No branches or pull requests

2 participants