Open romainmenke opened 7 months ago
@cdoublev said :
I think
<integer>
only exists for some corner cases of the CSS grammar. There should be a default rounding behavior in properties like order, z-index, etc.Another argument is that Number.isInteger(1.0) is truthy, probably like in most if not all progaming languages.
Anything with a decimal point should not be parsed as <integer>
, imho.
Agreed on that point. The only real point of contention, I think, is whether sci-not can produce integers - both 1e3
(very reasonable) and also 1.2e3
(equivalent to 1200, so maybe?)
How does producing an integer from scientific notation differ from producing it from decimal notation? It seems that both depend on evaluating the mathematical value of the input number. I have no math/cs degree so please forgive me if the answer is obvious.
Proposed: only produce <integer-token>
from signed/unsigned digits, other values are <number-token>
, which means only <number-token>
would serialize with sci-not and :nth-child(1e1)
would remain invalid.
IMO if 5.0
isn't an integer, it would be weird for 5.0e0
to be an integer.
https://drafts.csswg.org/cssom/#serializing-css-values
Could say that anything that serializes into an integer is actually an integer. That can't be the spec text, but conceptually that has few surprises.
Note that spec needs edits: https://github.com/w3c/csswg-drafts/issues/8538#issuecomment-1523755872
Ah right, we are still missing that edit, partially because of this issue (and partially because I forgot about it).
Okay, proposal:
A number is an integer if it either:
5.0
counts as "having a decimal component", so not an integer)5e0
is an integer, 5e3
is an integer, 5e-1
is not)5.0e0
is not an integer, 5.0e1
is an integer, 5.00e1
is not an integer.)The serialization edit from #8538 will satisfy this; since we serialize to no more than 6 digits after the decimal point, and scinot doesn't kick in for large number until it's substantially larger than a million, any large-number scinot will necessarily be parsed as an integer.
I might suggest dropping that last rule, I think it simplifies both the parsing rules and the mental model (No decimal points, no scinot that generates decimal points).
+1 to what is proposed here, I have personally run into many issues where this was a problem, and I know it's common enough that people are employing crazy hacks like assigning the <number>
to a dummy registered --integer
property.
However, I’d go even further: instead of debating whether a <number>
should be considered an <integer>
if it’s an integer, IMO a better solution would be to allow a <number>
to be used anywhere an <integer>
is expected, and just be converted to an <integer>
using some default rounding strategy (probably floor, which is what assigning to --integer
does today). Then the point discussed here becomes moot as there are very few cases where it still makes a difference.
I might suggest dropping that last rule, I think it simplifies both the parsing rules and the mental model (No decimal points, no scinot that generates decimal points).
Without that last point, you can't re-use numeric serialization code between JS and CSS (and other contexts). It's not uncommon to get large integers serialized with a decimal component and a large enough exponent to ensure it's a decimal.
IMO a better solution would be to allow a
<number>
to be used anywhere an<integer>
is expected, and just be converted to an<integer>
using some default rounding strategy
That would be a compat-risky change, as it would mean the properties and values that currently take integers, but might be written with a non-integer and currently ignored for invalidity, would become valid suddenly.
But also, it's separate from this change - regardless of whether we allow numbers where integers are expected, we can still define more things to be integers.
It seems a bit inconsistent that 1.2e1
is an integer, but 120e-1
is not?
That would be a compat-risky change, as it would mean the properties and values that currently take integers, but might be written with a non-integer and currently ignored for invalidity, would become valid suddenly.
Sure, but making invalid things valid is something we do all the time. We could do some compat analysis and see if it actually breaks anything. I think it would save authors from a lot of confusing mistakes.
The CSS Working Group just discussed [css-syntax] Should numbers have type `integer` whenever the actual value is an integer?
.
Sure, but making invalid things valid is something we do all the time. We could do some compat analysis and see if it actually breaks anything. I think it would save authors from a lot of confusing mistakes.
On z-index, I would be surprised if it didn't break things. People through random weird z-indexes at things to try and solve problems all the time, and often it doesn't work, and then they do something else but leave the inappropriate z-index behind. causing previously invalid z-index to become valid seems very likely to break things.
I think we actually resolved on this, but it was not reflected in the minutes. Does anyone else recall?
RESOLVED: add this parse time evaluation of scientific notation as integers
See : https://drafts.csswg.org/css-syntax/#consume-number
Also mentioned in passing by @tabatkins here : https://github.com/w3c/csswg-drafts/issues/6471#issuecomment-885945731
As a result of the current tokenizing rules these values have type
number
:10e3
1000.0
While both arguably represent integer values. Should the algorithm be updated to reflect this?
You can see the difference between numbers with type
number
andinteger
in action here : https://codepen.io/romainmenke/pen/GRLwLQyWrapping values of type
number
in a math expression already "normalizes" these into integers when possible. (e.g.z-index: calc(10e3)
works)