Re: [csswg-drafts] [css-color-5] Should colors nested in a parent color function (RCS, color-mix, light-dark, color-contrast) serialize in their most precision saving form (#10328)

@svgeesus I can give it a shot, but I'm not entirely confident. I spent a while looking at specs to find rules or guidance (CSSOM, CSS Values and Units, CSS Cascade) but it left me a bit more unclear than I would have liked. That said, here is my, likely overly verbose, take:

----

I think we should probably will want to have a sub-definition of the serialization of a color used as the origin color in another color. That might look like this:

> The serialization of a the declared value of a color used as the origin color inside of another color function (color-mix, RCS, color-contrast) is:
>
> For rgb(),rgba(),hsl(),hsla() - the string identifying the canonical color function, "rgb" for "rgb()" and "rgba()", "hsl" for "hsl()" and hsla()", in all-lowercase, followed by "(", followed by a space separated list of the non-alpha components as specified (numbers serializing as numbers, percentages serializing as percentages, angles serializing as canonicalized angles in degrees, calc() serializing in its simplified form) with no clamping applied, followed by " / " and the alpha component as specified (using the same rules as the color components) if an alpha component is present, followed by ")". (NOTE: the same serialization is used regardless of whether the modern or legacy syntax was used).
>
> For hwb(),lab(),lch(),oklab(),oklch() - the string identifying the color function in all-lowercase, followed by "(", followed by a space separated list of the non-alpha components as specified (numbers serializing as numbers, percentages serializing as percentages, angles serializing as canonicalized angles in degrees, calc() serializing in its simplified form) with no clamping applied, followed by " / " and the alpha component as specified (using the same rules as the color components) if an alpha component is present, followed by ")".
>
> For color() - the string "color(" followed by the canonical colorspace ("xyz-d65" for "xyz") in all-lowercase followed by a space, followed by a space separated list of the non-alpha components as specified (numbers serializing as numbers, percentages serializing as percentages, angles serializing as canonicalized angles in degrees, calc() serializing in its simplified form) with no clamping applied, followed by " / " and the alpha component as specified (using the same rules as the color components) if an alpha component is present, followed by ")".

Then, for relative colors, we could have:

> The serialization of the declared value of a relative color is:
>
> For rgb(),rgba(),hsl(),hsla() - the string identifying the canonical color function, "rgb" for "rgb()" and "rgba()", "hsl" for "hsl()" and hsla()", in all-lowercase, followed by "(from ", followed by the serialization of the origin color using the rules for serializing nested origin colors, followed by a single space, followed by space separated list of the non-alpha channel arguments as specified (identifiers serializing as identifiers, numbers serializing as numbers, percentages serializing as percentages, angles serializing as canonicalized angles in degrees, calc() serializing in its simplified form), followed by " / " and the alpha component as specified (using the same rules as the color channel arguments) if an alpha component is present, followed by ")".
>
> For hwb(),lab(),lch(),oklab(),oklch() - the string identifying the color function in all-lowercase, followed by "(from ", followed by the serialization of the origin color using the rules for serializing nested origin colors, followed by a single space, followed by space separated list of the non-alpha channel arguments as specified (identifiers serializing as identifiers, numbers serializing as numbers, percentages serializing as percentages, angles serializing as canonicalized angles in degrees, calc() serializing in its simplified form), followed by " / " and the alpha component as specified (using the same rules as the color channel arguments) if an alpha component is present, followed by ")".
>
> For color() - the string "color(from ", followed by the serialization of the origin color using the rules for serializing nested origin colors, followed by a single space, followed by the canonical colorspace ("xyz-d65" for "xyz") in all-lowercase, followed by a single space, followed by space separated list of the non-alpha channel arguments as specified (identifiers serializing as identifiers, numbers serializing as numbers, percentages serializing as percentages, angles serializing as canonicalized angles in degrees, calc() serializing in its simplified form), followed by " / " and the alpha component as specified (using the same rules as the color channel arguments) if an alpha component is present, followed by ")".

No doubt there is some factoring out that can be done to reduce redundancy, but for my initial take, being verbose seemed like the right choice.

In addition to the text, I have a set of examples I was trying to work from that I am including in a details section here

<details><summary>Details</summary>
<p>


Tablestakes. Given the following HTML snippet:

```html
<div id="example" style="background-color: red;"></div>
```

The output of following is said to be the "declared value serialization".

```js
document.getElementById("example").style["background-color"]
```

And the output of following is said to be the "computed value serialization".

```js
window.getComputedStyle(document.getElementById("example"))["background-color"]
```

----

Example 1: Basics

```html
<div id="example" style="background-color: lab(from red l a b);"></div>
```

Result "declared value serialization"
```css
lab(from red l a b)
```

Result "computed value serialization"
```css
lab(54.290539 80.804947 69.890961)
```
Notes: Declared value retains written form. Computed value serializes the resolved value.

----

Example 2: Spelling, whitespace and capitalization

```html
<div id="example" style="background-color: rgBA( fROm red R   g 1 );"></div>
```

Result "declared value serialization"
```css
rgb(from red r g 1)
```

Result "computed value serialization"
```css
color(srgb 1 0 1)
```
Notes: Declared value retains structure, but uses canonicalized spelling and capitalization (I would propose "rgba" -> "rgb", "hsla" -> "hsl", and "xyz" -> "xyz-d65") and one space between items. Computed value serializes the resolved value.


----

Example 3: color(...)

```html
<div id="example" style="background-color: color(from red srgb r g b);"></div>
```

Result "declared value serialization"
```css
color(from red srgb r g b)
```

Result "computed value serialization"
```css
color(srgb 1 0 0)
```
Notes: Declared value serializes colorspace after origin color like the grammar. Computed value serializes the resolved value.

----

Example 4: Percentages and angles 

```html
<div id="example" style="background-color: oklch(from white 10% c 40deg);"></div>
```

Result "declared value serialization"
```css
oklch(from white 10% c 40deg)
```

Result "computed value serialization"
```css
oklch(0.1 0 40)
```
Notes: Declared value serializes retains use of percentages and angles. Computed value serializes the resolved value, which always canonicalizes to numbers.

----

Example 5: calc() 

```html
<div id="example" style="background-color: rgb(from red calc(r / 2) g calc(30%));"></div>
```

Result "declared value serialization"
```css
rgb(from red calc(0.5 * r) g calc(30%))
```

Result "computed value serialization"
```css
color(srgb 0.5 0 0.3)
```
Notes: Declared value serializes calc() usages in their simplified form. Computed value serializes the resolved value.

----

Example 6: none 

```html
<div id="example" style="background-color: rgb(from red none g b);"></div>
```

Result "declared value serialization"
```css
rgb(from red none g b)
```

Result "computed value serialization"
```css
color(srgb none 0 0)
```
Notes: Declared value serializes retains use of none in channels. Computed value serializes the resolved value, which also serializes the none values.

----

Example 7: Nested none 

```html
<div id="example" style="background-color: hsl(from hsl(none 10% 50%) h s l);"></div>
```

Result "declared value serialization"
```css
hsl(from hsl(none 10% 50%) h s l)
```

Result "computed value serialization"
```css
color(srgb 0.55 0.45 0.45)
```
Notes: Declared value serializes the origin at full fedelity, no conversion to "rgb(140, 115, 115)". Computed value serializes the resolved value.


----

Example 8: Nested out-of-gamut rgb/hsl 

```html
<div id="example" style="background-color: hsl(from hsl(127.9 302% 25.33%) h s l);"></div>
```

Result "declared value serialization"
```css
hsl(from hsl(127.9 302% 25.33%) h s l)
```

Result "computed value serialization"
```css
color(srgb -0.511666 1.018266 -0.310225)
```
Notes: Declared value serializes unclamped origin, no-clamping values to range, no conversion to "rgb(0, 255, 0)". Computed value serializes the resolved value.


----

Example 9: alpha

```html
<div id="example" style="background-color: rgb(from red r g b / 100%);"></div>
```

Result "declared value serialization"
```css
rgb(from red r g b / 50%)
```

Result "computed value serialization"
```css
color(srgb 1 0 0)
```
Notes: Declared value serializes alpha only if it is specified explicitly in a channel. Computed value serializes the resolved value.

----

Example 10: currentcolor (NOTE: extra "color" declaration in HTML snippet)

```html
<div id="example" style="background-color: rgb(from currentcolor r g calc(b * 2)); color: blue;"></div>
```

Result "declared value serialization"
```css
rgb(from currentcolor r g calc(b * 2))
```

Result "computed value serialization"
```css
color(srgb 0 0 0.5)
```
Notes: Declared value serializes the same as elsewhere. Computed value serializes the **used** value, same as if "currentcolor" had been used on its own.



</p>
</details> 

-- 
GitHub Notification of comment by weinig
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10328#issuecomment-2135948165 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 28 May 2024 19:19:37 UTC