-
Notifications
You must be signed in to change notification settings - Fork 689
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-4] Computed value and serialization of Infinity
and NaN
in color functions
#8629
Comments
Yes, that's clearly wrong. The arguments aren't calculations, they're either keywords (channel names) or math functions. We should get a WPT enforcing this. Rendering is just a consequence of the "clamp it to your actual allowed range" behavior that V&U specifies for infinite (and other arbitrarily-large finite) values. I'm not sure what the actual behavior of a ginormous |
Also unsure. In our implementation for the
let color = new Color("lab(50% 0 0)");
color.coords[1] = Infinity
color
color.toGamut('srgb') |
I've added a few tests for serialization of I have no idea how |
If I am not mistaken, only nested math functions (unresolved before computed value) can produce
https://drafts.csswg.org/css-values-4/#top-level-calculation I think your tests should serialize
https://drafts.csswg.org/css-values-4/#calc-error-constants Hope it helps. =) |
Thank you @cdoublev I've changed the tests to lowercase |
The behavior of NaN is specified in https://drafts.csswg.org/css-values/#top-level-calculation - it gets censored to 0 when it would escape the calculation tree. It serializes as |
For
Would that be correct? |
Thanks for the clarification. My understanding of the spec was that it only serializes as
I am not in the position to give an answer but it would say yes, then. |
@romainmenke yes @cdoublev What part of the spec is leading you to believe that a top-level NaN doesn't serialize as such? I might have made a mistake. |
I've added some test for |
The part that we both referred to (edited for clarity):
Taking Example 38 following this part:
Basically my understanding meant that I am also missing why Chrome currently serializes the next example to
|
That's about how the value actually acts in the property it's used in, when the final result is a NaN. The simplification and serialization of the calculation itself is well-defined by the simplification and serialization algos, and they preserve NaNs at whatever level they show up in.
Looks like a bug. |
The tests were merged : web-platform-tests/wpt#39137 That only leaves the open question of how to handle enormous values :
I suspect the right value will just fall out of implementations that are free of bugs but maybe good to have a few examples/tests? @svgeesus Do you know or have an opinion on how something like Anyone writing |
All colors of the form Where |
This is specific to For Interesting, not what I would have guessed but it makes a lot of sense! |
Yes.
Yes (Negative values in XYZ are not supposed to occur, although they are possible as a result of chromatic adaptation; large negative ones should be treated as black I guess). |
@tabatkins Even if this is correct, per spec, why do we want this behavior? Does it have significant use-cases? Do other CSS properties perform this way? The reason I ask is because this would invalidate a couple major assumptions that chromium's color parser makes. Namely that the result of parsing a color function will either be failure or a Tests verifying this are part of interop 2023 and all UAs are currently failing: https://wpt.fyi/results/css/css-color/parsing/color-valid-lab.html To pass these tests will involve restructuring things quite a bit and creating a sort of "unresolved color" type so that the color can be serialized differently at parse time than at computed time. Obviously, none of this is impossible, but I simply wanted to highlight that it is a non-trivial amount of work to support. If it's a minor use-case and other UAs are uninterested in supporting it, than I'd propose changing the spec such that: For
And for
So, importantly, dropping the "calc" so that the channels are all numbers. Why is it important that they roundtrip in this context? |
Part of the reason for initially opening this issue is that dropping
Serializing into an invalid value seems like a bug to me. |
But maybe |
This is not to make something valid, this is done to express There will be other examples that don't have anything to do with color :) |
Thanks! I understand that now. So This makes sense. Now my next question would be, why are we forcing valid colors out of these inputs? Wouldn't the least surprising outcome for the user be to reject them entirely as colors? @svgeesus Apologies if there was already a debate about this that I missed out on, but from what I currently understand I think it would be best if these were all invalid colors. |
I certainly can't think of an actual use case for such colors. |
Is this something already happens in other values, functions, ...? All things that I am familiar with do not become invalid when out of range. |
There's no meaningful difference between
A number of things have ranges that are checked at parse-time. They'll be invalid if you use an out-of-range value by itself, but math functions change that behavior - see https://drafts.csswg.org/css-values/#calc-range. Instead, if a value is the result of a math function, it's treated as valid at parse time, and clamped at computed and/or used-value time to the allowed range. For example, This is why the serialization algorithm has a branch for computed or later values in the first step; specified values have to preserve the fact that the value is in a math function, in case the value is outside the allowed range, so you can round-trip the value.
This is required anyway to handle cases like a |
If we decide these are valid colors, then as far as I understand it:
Is that, in general, correct? If so, I'll start adding more test cases to wpt. |
More specifically, all math functions serialize as some variety of math function when they're specified values, regardless of what's inside them. If they've been able to simplify down to a single value, they'll serialize with a
Yup, correct. (And note, just for completeness, that the |
What about for Currently, Firefox does not parse non-finite inputs. Chromium and Safari do the following: input: Chrome and Safari also do this, which seems like definitely a bug: input: Should the proper behavior be: input: With -infinity going to zero as well? Also, what about for alpha channels, I would assume the following: input: input: input: Safari and Chrome turn For HSL/HWB I would assume that all channels are unbounded: infinity remains infinity and If I'm correct in all this I'll add some tests to WPT and to interop 2023. |
The CSS Working Group just discussed
The full IRC log of that discussion<fantasai> TabAtkins: Question was about if understanding of how infinity and nan showing up in color functions should be serialized at various value stages (and handled in general)<fantasai> TabAtkins: does run into question of whether to do earlier reolution for color functions <fantasai> TabAtkins: but aside from that <fantasai> TabAtkins: if you put an infinite calculation into an rgba(), the behavior is well-defined: clamp to the allowed range <fantasai> TabAtkins: I think for rgba() it's 0-255 <fantasai> TabAtkins: at at least computed value time <fantasai> TabAtkins: specified value time is separate issue <fantasai> TabAtkins: negative infinity clamps to zero <fantasai> TabAtkins: and NaN becomes zero when it escapes a calculation teree <fantasai> TabAtkins: that's all defined now <fantasai> TabAtkins: so unless there is any disagreement on these cases, we can confirm no change <fantasai> TabAtkins: and close the issue <fantasai> TabAtkins: only thing left is separate issue of whether we eagerly simplify certain math functions in some cases <fantasai> TabAtkins: but that's a separate issue <fantasai> fantasai: separate isssue is filed? <fantasai> TabAtkins: yes <fantasai> Rossen_: proposed resolution is no (further) chagne <fantasai> s/chagne/change/ <TabAtkins> (the separate issue is #8318) <fantasai> RESOLVED: No (further) change <TabAtkins> (#4 on the agenda this week, we skipped it because no Chris) |
This comment above says...
... like this code comment on WPT:
But this is not what I understand from what CSS Values and Units:
Out of range channel values are allowed in all color functions. Therefore I think it would be great to clarify when and how |
Re-opening because arguing on the basis of one legacy function |
What are the expected values and serializations for these examples?
lab(calc(Infinity) 0 0)
lab(50% calc(Infinity) 0)
lab(calc(NaN) 0 0)
lab(50% calc(NaN) 0)
manually setting these values seems illogical but they can be the result of calculations and variables. e.g.
calc(var(--foo) / var(--bar))
where--bar
is possibly zero.Currently browsers do very different things in some area's.
Chrome and Safari seem to agree that
lab(50% calc(Infinity) 0)
serializes aslab(50% Infinity 0)
, but that no longer roundtrips because the requiredcalc
was removed. That seems like an obvious bug, but maybe I overlooked something.Chrome renders
lab(50% calc(Infinity) 0)
as white.Safari renders
lab(50% calc(Infinity) 0)
as black.Chrome also sometimes renders a pink area in certain edge cases
WPT doesn't have any tests for these kinds of values.
The text was updated successfully, but these errors were encountered: