Open LeaVerou opened 4 months ago
Yes, I removed <number-percentage>
because it's unsound as a type. You can multiply anything by a number and keep its type stable; multiplying by any typed value changes the type (and eventually needs a division to get us back to a useful type).
Percentages are potentially resolveable to anything. Currently, with the restriction against combining percentage and number in calculations, I can immediately infer the type of an expression containing percentages, even if I have no idea what the percentage resolves to yet. If they were combinable, tho, then I couldn't.
Now, granted, previously every instance that could have combined numbers and percentages was using them in a trivial way - the numeric range was either 0-1 or 0-100, so whether you spelled something .25
or 25%
was just a stylistic choice. The presence of non-trivial reference ranges in the newer color syntaxes makes this a little unfortunate.
Yes, I removed
<number-percentage>
because it's unsound as a type. You can multiply anything by a number and keep its type stable; multiplying by any typed value changes the type (and eventually needs a division to get us back to a useful type).
But once you know how to convert between the two, why not handle it seamlessly? E.g. h + 20deg + 30
does make sense, just like 20% + 1em + 10%
makes sense in <length-percentage>
.
Percentages are potentially resolveable to anything. Currently, with the restriction against combining percentage and number in calculations, I can immediately infer the type of an expression containing percentages, even if I have no idea what the percentage resolves to yet. If they were combinable, tho, then I couldn't.
Why is this a problem?
(FWIW I’m not suggesting we expose these to authors via @property
, only to use them internally for RCS)
Now, granted, previously every instance that could have combined numbers and percentages was using them in a trivial way - the numeric range was either 0-1 or 0-100, so whether you spelled something
.25
or25%
was just a stylistic choice. The presence of non-trivial reference ranges in the newer color syntaxes makes this a little unfortunate.
Yup.
The type arithmetic doesn't allow <number-percentage>
, so we will never allow a calc tree that adds a number to a percentage.
On the other hand, the usage in the examples looks totally legit, because there's a clear context that the percentages should be resolved into numbers.
So can we solve it at parsing time? We introduce a treat-percentage-as-number mode for parsing certain <number>
values (like a color channel), so that percentages are immediately converted into numbers at parsing time, and we never really create a <number-percentage>
value. This also follows the idea of calc simplification that calc expressions are eagerly simplified at the earliest possible time.
@xiaochengh I think that would be fine. I’m assuming both of these would work, right?
background: oklch(from var(--color) calc(l + 20%) c h);
--offset: 20%;
background: oklch(from var(--color) calc(l + var(--offset)) c h);
Yes, both should work.
Fwiw, in #9395:
RESOLVED: % that are resolved against numbers do that at parse time
The issue was also about resolving <percentage>
to <angle>
at parse time (as noted in the title of the issue but not in the initial comment though). So opacity: calc(50% + 0.5)
or background-color: hsl(from blue calc(h + 30deg) calc(s + 25%) calc(l + 5%))
would be valid. edit: it does not fix h + 30deg
, which would require to determine the type of h
as <angle> | <number>
, I think.
That said, I am not fond of resolving values at parse time, whether it is naked or inside a math function. Would you also allow font-weight: calc(bold + 100)
, since bold
could be resolved to <number>
at parse time?
This was prompted by this Chrome bug report: https://issues.chromium.org/issues/41483822
The author was trying to do things like:
and found they were not working in Chrome (whereas their
<number>
counterparts don't work in Safari, that implements an older version.As I wrote in the issue…
However, it does present a clear ergonomics issue. Also, going from numbers to percentages in certain color formats is not just a matter of removing the unit, or even dividing by 100, but can be a lot more complex (e.g. in device independent colors, percentages provide a reference range that roughly corresponds to a cylinder encompassing the P3 gamut).
I think we used to have a
<number-percentage>
type at some point and we removed it (@tabatkins do you remember why?). I wonder if we could reinstate it? This seems like the perfect use case. We'd also need a<number-angle>
for hues, but that is needed far less.