Re: [csswg-drafts] [css-values-4] What should non-calc() math functions serialize to when they're fully resolved? (#4399)

The CSS Working Group just discussed `What should non-calc() math functions serialize to when they're fully resolved?`, and agreed to the following:

* `RESOLVED: All math functions aggressively simplify their calculations as far as possible for a given value-computation stage.`
* ``RESOLVED: If numeric simplification of a math function results in a single value, the serialization is that value wrapped in `calc()` ``

<details><summary>The full IRC log of that discussion</summary>
&lt;dael> Topic: What should non-calc() math functions serialize to when they're fully resolved?<br>
&lt;dael> github: https://github.com/w3c/csswg-drafts/issues/4399#issuecomment-554535978<br>
&lt;dael> TabAtkins: I brought up a question about when a non-calc() math function is fully resolved what should it be serialized as? We have old calc rules tht say if you do 1px+1em you combine at computed value and serialize as 17px. If you have min(10px, 20px) what should it serialize as? We can resolve it to 10px or should we preserve it was a min calculation?<br>
&lt;AmeliaBR> Do we ever need to keep at least a function wrapper for the same reasons as `calc(-10px)` needs to keep a wrapper?<br>
&lt;dael> TabAtkins: I'm neutral to where we go. Current text simplifies everything as far as possible which might land on a plain number. Simon preferred preserving root node's identity.<br>
&lt;dael> TabAtkins: I can do that, not a big deal in spec text. Just some annotation. I want to know what the other impl opinions are<br>
&lt;dael> smfr: Need to have a distinction between spec and computed. Most of my questions were about specified value. Text about simplification implies it's on specified value.<br>
&lt;dael> smfr: How much simplification happens on the specified value and then what happens on computed. I prefer computed simplified as mucht as possible to a bare value if possible. Specified value is how much do you want to round trip or is it okay to collapse redundant mins?<br>
&lt;AmeliaBR> Agree with smfr: if simple serialization converts `calc(200px/4)` to `50px`, then it makes sense to do the same with simple  mathematical min/max<br>
&lt;dael> TabAtkins: Is spec I do full simpliciation on specified. I realize from your comment I'm too agressive. Still have the question about what is the best to do with a min that has identical units? Does it retain its structure at spec value time?<br>
&lt;dael> TabAtkins: I can go either. I can do light that combines idential units like old calc did or I can do more agressive and not cannonicalize units.<br>
&lt;dael> emilio: Browsers do cannonicalize units, right?<br>
&lt;dael> TabAtkins: At specified value I don't think calc(1in) becomes px<br>
&lt;dael> emilio: calc(1px+1q) I get 10.something px.<br>
&lt;dael> smfr: Different units get cannonicalized<br>
&lt;dael> TabAtkins: So the tests smfr were wrong?<br>
&lt;fantasai> :/<br>
&lt;dael> smfr: Lots of incompat. WPT have a mixture of behaviors so I don't thinkw e should go on what those tests are doing<br>
&lt;dael> smfr: One of the consideratiosn for specified value is are there authoring tools that expect nested calc to be preserved. I know glazou was concerned back in 2017 because it would break authoring tools.<br>
&lt;dael> TabAtkins: At time we resolved getting rid of nested calc was fine. The loss to authoring tools was considered to be fine due to simplifications in impl and easier for end user.<br>
&lt;dael> TabAtkins: Don't want to revisit that if possible. Still a range of stuff we can do. I don't want to preserve more than the old calc. I prefer preserve as little as possible<br>
&lt;astearns> ack fantasai<br>
&lt;dael> fantasai: calc if nested is eq/ to parans. Switching min or max is a little different. Not quite the same situation<br>
&lt;dael> TabAtkins: I would argue same as dsitributing multiplication across properties. That's a re-write of algebraic structure which seems similar to simplifying away a min<br>
&lt;dael> fremy: I was hearing emilio and I found Chrome behavior is weird. If you set border calc(1inch) you get back calc(1inch) but calc(1in+1px) you get 97px. I think ther'es not web compat and we an do what feels right<br>
&lt;dael> TabAtkins: That's super weird, that feels like us going we're done and can exit early<br>
&lt;emilio> fantasai: document.body.style.left = "calc(1q)"; document.body.style.left<br>
&lt;emilio> Firefox behaves the same as Chrome here, but agreed it feels weird<br>
&lt;dael> TabAtkins: Proposal: Since calc in general does do agressive simplification we preserve that through the new math expressions. At specified value time we simplify down. Maybe preserve root node at specified time, but that's thrown away at computed value time<br>
&lt;dael> TabAtkins: Does that sound fine and, if so, which way on the root node?<br>
&lt;dael> smfr: Prefer preserve the root node. If you have calc with a nested min and you could reduce, I don't know if you should<br>
&lt;emilio> fremy: fwiw what happens on Firefox is that as soon as we need to canonicalize `&lt;length>`s we simplify both to px<br>
&lt;dael> smfr: Keeping root node as a function is right. And simplify as much as possible for computed<br>
&lt;dael> TabAtkins: Will argue to get rid of nested things. min is a binary operator square root is. Preserving the later things as functions seems inconsistant to me<br>
&lt;AmeliaBR> q+<br>
&lt;dael> smfr: That implies if you have a calc with min inside you'd replace the calc with a min?<br>
&lt;dael> TabAtkins: No, the root node retains at specified value.<br>
&lt;dael> smfr: Doesn't change function type?<br>
&lt;dael> TabAtkins: Yeah. Preserved. Everything under simplifies as much as possible. calc(min(px,%)) stays. calc(min(px,px)) simplifies<br>
&lt;dael> emilio: I'm fine with dropping root, but I don't mind<br>
&lt;emilio> fantasai: in the case of FF it's just an accident fwiw<br>
&lt;dael> AmeliaBR: I agree with arguments, but I think we lost them a long time ago. I don't like that we do a lot of math simplification at serializtion with calc, but we do. calc(10px/3) reads back as calc(3.333px).<br>
&lt;dael> AmeliaBR: Similar logic in the other functions seems to be a consistency thing. Important to keep the wrapper that says this is a math function b/c rules about clamping.<br>
&lt;emilio> fremy: fantasai: https://searchfox.org/mozilla-central/rev/652014ca1183c56bc5f04daf01af180d4e50a91c/servo/components/style/values/specified/length.rs#391, fwiw<br>
&lt;dael> AmeliaBR: That would presumably happen with other math functions too. If you say in spec value min(10px,20px) it should still read back with functional wrapper of min(10px) as simplified.<br>
&lt;emilio> fantasai: so it sorta makes sense, we preserve the unit as much as possible, but drop it if needed<br>
&lt;astearns> ack AmeliaBR<br>
&lt;dael> AmeliaBR: You want to keep b/c what happens if it's min and a value is negative and negative is invalid in that context. We need the wrapper<br>
&lt;dael> TabAtkins: If you forget the root node it serliazes as a calc.<br>
&lt;dael> AmeliaBR: Do we turn all simplified math functions into a calc wrapper is the question?<br>
&lt;dael> TabAtkins: Yep<br>
&lt;dael> AmeliaBR: Then yeah, simplifying...if the result is a single value it makes sense as a single value with a calc wrapper rather than preserve min/max when we can't do that with other functions<br>
&lt;dael> astearns: We're proposing to simplify functions like we do calc and change calc specified value to retain the wrapper<br>
&lt;dael> TabAtkins: CHanging the new stuff.<br>
&lt;dael> TabAtkins: The root node of a calculation tree retains it's identify<br>
&lt;dael> astearns: If root is calc function?<br>
&lt;dael> TabAtkins: Then it's a calc<br>
&lt;dael> TabAtkins: That's preserved in specified. At computed it goes away.<br>
&lt;dael> astearns: functions simplify the way calc does. Outer most function context is maintained for new functions.<br>
&lt;dael> AmeliaBR: I have a problem with the second. Should we get the first resolved?<br>
&lt;dael> TabAtkins: I'll write proposed resolution<br>
&lt;TabAtkins> Proposed resolution 1: All math functions aggressively simplify their calculations as far as possible for a given value-computation stage.<br>
&lt;dael> astearns: Objections or continued discussion on proposed resolution 1?<br>
&lt;dael> RESOLVED: All math functions aggressively simplify their calculations as far as possible for a given value-computation stage.<br>
&lt;dael> astearns: TabAtkins will you type the 2nd?<br>
&lt;TabAtkins> Proposed resolution 2: At specified-value time, the root of a calculation tree retains knowledge of what type of function it is and serializes accordingly, even if it could be simplified to a single number. (At computed-value time, they'll turn into a plain number if possible.)<br>
&lt;dael> TabAtkins: Yeah<br>
&lt;dael> AmeliaBR: Problem with root of calc tree retaiining knowledge is some function types are math operators like power. If you simplify square root of 4 it means erase function wrapper<br>
&lt;dael> TabAtkins: The be precise here I would not simplify root node, start simplification at children of root node<br>
&lt;dael> AmeliaBR: If I have squareroot 4 inside a calc it's simplified, but sqt4 is not simplified?<br>
&lt;dael> TabAtkins: Correct. It's either all or none. I don't want to keep min but not sqrt<br>
&lt;TabAtkins> calc(sqrt(4)) => calc(2); sqrt(4) => sqrt(4)<br>
&lt;dael> AmeliaBR: COnsidering sqrt and power anything simplified to a single value simplifies to that wrapped in a calc.<br>
&lt;dael> TabAtkins: THat's int he spec today. smfr expressed desire to keep root node around. Easy to do spec wise.<br>
&lt;dael> smfr: I think AmeliaBR is suggesting sqrt(2) that becomes calc(2.14...). You replace sqrt with calc.<br>
&lt;dael> TabAtkins: That's spec today<br>
&lt;AmeliaBR> yes, serialization of `sqrt(4)` would be `calc(2)`<br>
&lt;dael> florian: DOes spec say [missed]<br>
&lt;dael> TabAtkins: No<br>
&lt;dael> florian: I think that's what AmeliaBR is suggesting<br>
&lt;dael> TabAtkins: AmeliaBR are you suggesting extra calcs?<br>
&lt;dael> AmeliaBR: If we need a wrapper use cal<br>
&lt;fantasai> s/2.14/1.41/<br>
&lt;dael> florian: calc(sqrt(4)) what is that?<br>
&lt;AmeliaBR> Also `min(10,20)` serializes as `calc(10)`<br>
&lt;dael> florian: calc(2) or calc(calc(2))<br>
&lt;dael> AmeliaBR: YOu just need the outer wrapper<br>
&lt;dael> florian: That is current spec<br>
&lt;dael> AmeliaBR: I think we're at the point where everyone understands, but not consensus on strategy<br>
&lt;dael> TabAtkins: I think we've converged. I was arguing smfr wants exact ID but that's nto case. WE fully simplify. At specified value time we need to wrap it in a calc if it's  single number. So no change to current rules for calculation trees<br>
&lt;dael> smfr: Root function might be a calc. Might still be a min/max<br>
&lt;dael> TabAtkins: Yes, if you can resolve min it's a min.<br>
&lt;dael> smfr: I like that calc is way to signal out of range things<br>
&lt;dael> TabAtkins: We can go with no change to current rules for calculation trees if no objection?<br>
&lt;dael> AmeliaBR: I'm writing down a version<br>
&lt;AmeliaBR> Proposed resolution: if numeric simplification of a math function results in a single value, the serialization is that value wrapped in `calc()`<br>
&lt;dael> smfr: Current rules is ambiguous.<br>
&lt;dael> TabAtkins: New version os spec shouldn't be ambigous. I'll put in a note that it stays a calculation tree is clear. IT's in spec, but easy to go past.<br>
&lt;dael> smfr: I meant there are 3 specs and not sure which people are talking about.<br>
&lt;dael> smfr: ED right?<br>
&lt;dael> TabAtkins: Yeah<br>
&lt;dael> astearns: TabAtkins is AmeliaBR proposed resolution what you're thinking about?<br>
&lt;dael> TabAtkins: Fine<br>
&lt;dael> TabAtkins: End result is no change, but the explicit wording works<br>
&lt;dael> smfr: Spec could be if you encounted bare math you open calc<br>
&lt;dael> TabAtkins: I'll work with you in the issue to make it super clear<br>
&lt;dael> smfr: Still want clarity on unit canonicaliztion happens<br>
&lt;dael> TabAtkins: We'll continue that in issue<br>
&lt;dael> astearns: Objections to if numeric simplification of a math function results in a single value, the serialization is that value wrapped in `calc()`<br>
&lt;dael> RESOLVED: If numeric simplification of a math function results in a single value, the serialization is that value wrapped in `calc()`<br>
&lt;dael> astearns: Please do continue about unit canonization in the issue<br>
</details>


-- 
GitHub Notification of comment by css-meeting-bot
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4399#issuecomment-556160413 using your GitHub account

Received on Wednesday, 20 November 2019 17:44:34 UTC