-
Notifications
You must be signed in to change notification settings - Fork 637
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
[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
Comments
This makes total sense to me. Agenda+ so we can resolve ASAP. |
My reading is that channel values must never be clamped in a relative color. But I agree that it should also apply to colors nested in other color functions. I would still resolve |
The question isn't really about clamping per-se, but rather about serialization of those unclamped values. |
Ah yes. I was thinking of converting hsl to rgb without clamping, to be consistent with how top-level absolute color functions serialize, and you propose to serialize the list of component values (with simplified math functions, omitted optional values, etc). Your proposition is also my preference but, and to expand on this #10327 (comment), I do not know/understand why all absolute color functions are partially or entirely resolved when serializing them as components of a declared value, which seems to also be your point in #10305. Therefore my reasoning is confused (sorry). |
@weinig could you propose replacement spec text for the part starting
I think we would come to consensus on a call more rapidly if there is specific proposed text, rather than a general point whose wording then needs to be discussed and agreed upon. |
@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:
Then, for relative colors, we could have:
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
Tablestakes. Given the following HTML snippet: <div id="example" style="background-color: red;"></div> The output of following is said to be the "declared value serialization". document.getElementById("example").style["background-color"] And the output of following is said to be the "computed value serialization". window.getComputedStyle(document.getElementById("example"))["background-color"] Example 1: Basics <div id="example" style="background-color: lab(from red l a b);"></div> Result "declared value serialization" lab(from red l a b) Result "computed value serialization" 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 <div id="example" style="background-color: rgBA( fROm red R g 1 );"></div> Result "declared value serialization" rgb(from red r g 1) Result "computed value serialization" 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(...) <div id="example" style="background-color: color(from red srgb r g b);"></div> Result "declared value serialization" color(from red srgb r g b) Result "computed value serialization" 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 <div id="example" style="background-color: oklch(from white 10% c 40deg);"></div> Result "declared value serialization" oklch(from white 10% c 40deg) Result "computed value serialization" 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() <div id="example" style="background-color: rgb(from red calc(r / 2) g calc(30%));"></div> Result "declared value serialization" rgb(from red calc(0.5 * r) g calc(30%)) Result "computed value serialization" 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 <div id="example" style="background-color: rgb(from red none g b);"></div> Result "declared value serialization" rgb(from red none g b) Result "computed value serialization" 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 <div id="example" style="background-color: hsl(from hsl(none 10% 50%) h s l);"></div> Result "declared value serialization" hsl(from hsl(none 10% 50%) h s l) Result "computed value serialization" 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 <div id="example" style="background-color: hsl(from hsl(127.9 302% 25.33%) h s l);"></div> Result "declared value serialization" hsl(from hsl(127.9 302% 25.33%) h s l) Result "computed value serialization" 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 <div id="example" style="background-color: rgb(from red r g b / 100%);"></div> Result "declared value serialization" rgb(from red r g b / 50%) Result "computed value serialization" 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) <div id="example" style="background-color: rgb(from currentcolor r g calc(b * 2)); color: blue;"></div> Result "declared value serialization" rgb(from currentcolor r g calc(b * 2)) Result "computed value serialization" 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. |
Wow, thanks for the very thorough response! |
The CSS Working Group just discussed
The full IRC log of that discussion<fantasai> scribenick: fantasai<fantasai> ChrisL: The nesting of things with color-mix()/light-dark()/ etc. was not fully specified <fantasai> ChrisL: We discussed some, and we have some proposed replacement text that looks extremely detailed and accurate to me <fantasai> ChrisL: So I'd like to adopt into the spec <ChrisL> https://github.com//issues/10328#issuecomment-2135948165 <fantasai> RESOLVED: Adopt the proposed text |
In CSS Color 5, the serialization of relative colors is defined with the following:
(emphasis added)
If taken at face value, this would mean that relative colors do not round trip faithfully when the origin color has values outside the reference range, as the processing model for relative colors states:
So, in an example like:
my reading is that the declared value would serialize as:
hsl(from rgb(0, 255, 0) h s l)
, but the computed value would becolor(srgb -0.511666 1.018266 -0.310225)
I would like to propose that nested colors, both for RCS and the other color functions that take color arguments, the nested colors serialize in a way that preserves the behavior of the parent. The most straightforward way I can think to have that work would be to serialize the declared value according to normal (not encumbered by the legacy of color serialization) CSS serialization rules for declared values - aka minimal needed, calc() preserving, etc.
In the case above, that would mean serializing the declared value exactly as written:
To expand with another example:
would serialize the declared value as:
The text was updated successfully, but these errors were encountered: