-
Notifications
You must be signed in to change notification settings - Fork 658
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] Allow division of same types in calc() #545
Comments
@jpamental and I just found another use case: Variable fonts that smoothly change width and/or weight as the viewport is resized via dividing a length with viewport units. |
Seems like @tabatkins is talking about similar math issues here: #581 |
Yeah, this was in the plans for Level 4 (since it was deferred out of L3). CSSWG just resolved to add it back to L4, so just needs edits at this point. |
For the record, one place (out of possibly more than one) where the group resolved to add unit algebra to |
I think my only review comments, after reviewing 8.1.2. Type Checking are:
|
The Working Group just discussed The full IRC log of that discussion<dael> Topic: Allow division of same types in calc()<dael> github: https://github.com//issues/545 <dael> astearns: Looks like there's a change for this <dael> TabAtkins: I think all that's left is...I wanted review by WG <dael> TabAtkins: I added the resolution from months ago to allow unit algebra in calc(). dbaron gave me review which I hadn't seen yet. I'll resolve those. Any other comments or concerns please let me know. It's i n the spec <dael> frremy: I'm wondering how you decided the final unit value of a calc. You prob have to back track. I think we have to change how we do this. Seems fine by me, but it requires keeping track of more things <dael> TabAtkins: Yep, how to determine type it resolves to is in the spec and you need the algo to do Typed OM. I leaned on Typed OM as much as possible b/c I think I got it right <dael> chris: This is the correct thing to do. It's compat with typed OM we should do this. <dael> astearns: This edits is a result of a resolution? <dael> TabAtkins: Yes. We've had multiple resolutions to do this. dbaron found one in 2014. this is just a review request. <chris> 2014, wow <dael> astearns: Sounds like dbaron looked. chris and frremy are okay. I think we're good. Anyone else wanting to look please do. |
I agree with @dbaron that "negating" types is confusing wording.
Based on the decision in #2337, there is no longer any need to keep track of the distinction between numbers and integers: the calculation can happen as full numbers, and integer clamping happen on the final value. More comments on @tabatkins' edits:
|
Sigh, I knew that would be problematic, but hoped it was okay to be short with it. I added an "invert a type" algo to TypedOM and am using it directly now.
As Amelia said, that distinction is no longer necessary.
Interesting, what problems do you foresee? It should be identical to the existing clamping behavior for very-large-but-finite values; I can't imagine anything that would distinguish it from that case.
I don't particularly care; if it becomes a publication issue I'll move things, but otherwise I'll just leave them where they are.
I think that would be a distraction from the spec text. Even in Typed OM, the algorithms for types are off in their own subsection, separated from the actual operations that use them, because the details aren't particularly relevant for understanding things. The fact that following the definitions jumps to another document instead of a same-document separate section isn't a particularly relevant difference here.
Good catch, done.
I see the value of this, but I'm currently relying on it being last so I can say "anything else". For consistency I'd also have to move the final bullet point up, and I think it reads best put at the end.
Sure, it's some indirection, but it's identical to the type-determining line of the I'm similarly against trying to inline the algorithms for multiplication and division.
Ah, this is true. I'll simplify.
They do define mutually-exclusive types among the types that I listed. I didn't say that it can resolve to the
I don't understand what needs to be updated - I wrote the spec text with the assumption that the issue would be resolved in the way I wanted, so it already defines how to handle
Updated from future to present tense. ^_^ |
So for clamping of infinities, a few things (though maybe not what I was thinking at the time):
|
It wasn't previously defined either, that's up to individual properties and/or user-agent choice. Again, you could always define an arbitrarily large value in calc(); infinity is just slightly larger than that. ^_^
Ah, I didn't mean to restrict it to used-values only. Fixed.
I dunno either.
I rewrote it to be more specific, specifying exactly which operations produce infinities or NaNs, and how infinities or NaNs affect operations they show up in. I defined "top-level calculations" to be any of the expression arguments to min()/max()/clamp(), or a non-nested calc(); these censor NaN by turning it into positive infinity, while non-top-level calculations are still allowed to produce NaN. (So in particular, I went ahead and dropped negative-zero tracking, tho I'm not sure if I should. There are only two ways to produce a negative zero in 754 semantics: explicitly negate a zero (or an expression resulting in zero), or divide a finite number by negative infinity. calc() can't negate things, only subtract them, and subtraction will never result in -0 unless one of the arguments is -0 already. So we're left with dividing by negative infinity. Unless there's some difficulty with implementations having semantics differenting from 754, I'd rather just pretend that particular case doesn't exist. But if it does become a problem, I'm fine with explicitly specifying how it works, too. |
Agenda+ to ask about whether I should keep negative-zero tracking within an expression. (The distinction will disappear when it exits a top-level calculation, at the same time as NaNs disappear.) Specifically, should |
Mmmmm, I have the impression dividing by zero is currently disallowed by all browsers. If yes, no opinion, since there isn't an implementation of this yet. |
https://wptest.center/#/lr3dp8 (testcase in case someone else want to try this before the call) |
Yes, we changed that (because we have to - you can't tell at parse time if |
The Working Group just discussed
The full IRC log of that discussion<dael> Topic: Allow division of same types in calc() should calc(1 / calc(1/(-1/0))) produce positive infinity or negative infinity?<dael> github: https://github.com//issues/545#issuecomment-394474713 <dael> TabAtkins: In the corse of proting typed OM into calc, typed OM depends on float semantics but in calc CSS values don't theoretically have a float semantic bound. I have to define certain cases. Division by 0 produses postiive or negative infinity and it's clamped. I followed ieee semantics. ieee754 semantics track positive and negative. Css doesn't normally care about it. <dael> TabAtkins: Depending on what you're doing you can construct something that resolves to postive or negative infinity. So far for simplicity I've ommited them but it's not hard to add them back in. I suspect we would want that because it's simpler for typed OM and calc to match in these cases. Wanted to verify <TabAtkins> calc(1 / calc(1/(-1/0))) <dael> TabAtkins: In issue I have an example ^ <dael> TabAtkins: Resolves differently. It double inverts a negative inifity and will be positive or negative depending on if a negative 0 escapes the inner calc. <dael> TabAtkins: I propose we track 0 signedness to be consistant with general float semantics. <dael> fremy: No objections. Still wondering why track inifity. We can say it's not a number so it doesn't matter. <dael> TabAtkins: If you're approaching a 0 in the denominator of something you don't want to suddenly flip. The infinities have to be something. If they're all positive if something is approaching inifnity it'll flip to positive and go from really big to really small. <dael> TabAtkins: Typed OM is just math over JS numbers and they have infinities. <dael> TabAtkins: We could expose extra semantics but it doesn't buy us anything. <dael> fremy: If you animate the denominator from -1 to 0 when you get to 0 it's positive. There isnt' a browser supporting it so it's not a huge use case. <dael> TabAtkins: I know it's a new feature. There's no compat to worry about. <dael> TabAtkins: If all infinities go 0 and you have -1/-1 and then bottom goes to 0 -1/0 should be negative. <dael> fremy: -1/-1 is positive. <dael> TabAtkins: Sorry, meant the other way. <dael> fremy: -1/-1 goes to a positive 0. But okay, it's fine. I'm fine with whatever you want. <dael> TabAtkins: I'm not making up semantics. I'm saying follow ieee as close as possible. <TabAtkins> \/kick NegativeInfinity <dael> AmeliaBR: I agree with TabAtkins that it makes sense to be consistent with standard computer math that's already in JS. Also important b/c CSS we are animmting values and once we're allowing people to divide different lengths like font size/viewport width and animate to 0 this could come up. Continuous animations until something turns infinite makes sense. <dael> astearns: Other impl opinions? <dael> astearns: dbaron do you have an opinion? <dael> dbaron: No strong opinion <dael> astearns: Other opinions? <dael> astearns: I'm hearing people call for dealing with negative 0. No opinions against. <dael> astearns: Objections to allowing calc to handle negative 0s? <dael> RESOLVED: Allow calc to handle negative 0s |
The reason that division by a
<length>
was originally not allowed was that in some cases there was no way of knowing whether that was a division by 0, and before Variables there was no such concept as invalid in computed value time. Now that there is, perhaps we can revisit this issue for Values 4.This is especially useful in conjunction with CSS Variables, as currently one can convert from a
<number>
to a<length>
(or<angle>
etc) but there is no way to convert a<length>
to a<number>
! Also, calculating the ratio of two lengths is often very useful, e.g. what percentage of the viewport width is500px
?calc(500px / 100vw)
! Not to mention that this would be a more consistent, less surprising design.The text was updated successfully, but these errors were encountered: