Skip to content
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-values] calc() should round when it's used as an <integer> #2337

Closed
tabatkins opened this issue Feb 20, 2018 · 6 comments
Closed

[css-values] calc() should round when it's used as an <integer> #2337

tabatkins opened this issue Feb 20, 2018 · 6 comments
Labels
css-values-4 Current Work

Comments

@tabatkins
Copy link
Member

Right now, calc() carefully tracks whether a numeric expression (no units or %s) is guaranteed to resolve to an integer, or might resolve to a more general number. This allows it to be used in places like z-index safely.

However, it excludes some expressions that would be integral if evaluated - for example, any division makes it non-integral, even in an expression like calc(4 / 2).

This restriction also seems somewhat inconsistent with calc()'s treatment of range restrictions - if you specify width: calc(-1px);, it's valid (and equivalent to 0px), but if you specify z-index: calc(4 / 2);, it's invalid. It seems like this was accidentally motivated by what can be expressed directly in the grammar (integer vs real) vs what has to be expressed in prose as an additional constraint (range restrictions), but these really shouldn't be treated differently.

In particular, this causes some trouble for TypedOM, which wants to make it so that CSSUnitValues (corresponding to plain numbers and dimensions) get the same protection against being out-of-range that calc() does, but now we've realized that there's no such "should be an integer, is actually a real" protection that we could also apply.

So! I propose that we remove the tracking of <integer> vs <number> in calc() (it's already no longer tracked in the typing algorithms of Typed OM, which will be used in calc(), per WG resolution, when I finally write up the unit-algebra text), and instead say that if a calc() ends up being non-integral when an integer is required, it is automatically rounded to the nearest integer.

(Detail: I provisionally propose we use "toward positive infinity" rounding, same as JS's Math.round(). Does CSS already have any rounding we should match instead?)

@alancutter
Copy link
Contributor

I provisionally propose we use "toward positive infinity" rounding, same as JS's Math.round(). Does CSS already have any rounding we should match instead?

This matches integer animation rounding.
https://www.w3.org/TR/css-transitions-1/#animtype-integer

@Nadya678
Copy link

Nadya678 commented Feb 22, 2018

I think the precision of returned values (for non-integer) should be "unrestricted double"

According to the draft that defines getBoundingClientRect https://drafts.fxtf.org/geometry-1/#domrect
https://drafts.csswg.org/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods
the precision of height and width should not be less that the defined for compatibility.

@tabatkins
Copy link
Member Author

This is about abstract CSS values, not any JS API.

@FremyCompany
Copy link
Contributor

FremyCompany commented Feb 22, 2018

Edge already supports that, and floors down towards 0.

https://wptest.center/#/udafb2 (Calc rounding to integers)

I would have a weak preference for not having to change that, but if there are people with strong opinion in favor of rounding up, I could be convinced otherwise.

@tabatkins
Copy link
Member Author

The fact that CSS already animates integers by rounding towards positive infinity is, I think, a pretty strong argument for calc() doing the same thing by default.

@css-meeting-bot
Copy link
Member

The Working Group just discussed [css-values] calc() should round when it's used as an <integer>, and agreed to the following resolutions:

  • RESOLVED: Accept the proposal in #2337
The full IRC log of that discussion <dael> Topic: [css-values] calc() should round when it's used as an <integer>
<dael> github: https://github.com//issues/2337
<dael> TabAtkins: Basic issue, when you put an invalid number in the calc due to range restrictions we clamp instead of call it invalid. But we try and track int or number to reject at parse time. If you do division it becomes a number. THis is inconvenient for typed OM. We'd like any numbers to work out.
<dael> TabAtkins: I think the distinction for int and number I wrote in is for conveince not a need. I propose if a prop only takes an int and calc in non-int we round to an int. We do this for animations already.
<dael> TabAtkins: To match how animations of int are specified at 0.5 we round up.
<dael> Rossen_: Any other opinions
<dael> Rossen_: Or suggestions
<tantek> that sounds like a reasonable proposal and way of re-using another approach of how we deal with this situation
<dael> AmeliaBR: I believe someone said edge does this?
<dael> TabAtkins: fremy said they do but they floor so he had a weak preference for that. I think match animations is better.
<dael> AmeliaBR: Yes, doing actual rounding sounds more logical.
<dael> Rossen_: Wouldn't disagree. For matching with flooring or animations I'd also prefer animations.
<dael> Rossen_: So I would be fine with TabAtkins proposal.
<dael> Rossen_: Any other ideas or suggestions? If not we can resolve to accept current.
<dael> Rossen_: Objections?
<dael> RESOLVED: Accept the proposal in #2337

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-values-4 Current Work
Projects
None yet
Development

No branches or pull requests

5 participants