Re: [csswg-drafts] [css-values-5] issues with interpolation rules for calc-size() (#10220)

Wait, damn, I actually still lose linear interpolation in this model; the spec specifies that you interpolate the basises. And I can't just naively expand the nested function into the outer one, even if I made "sequence of calculations" actually valid in the grammar, because both sides of the interpolation might have this.

Example:
Imagine you're interpolating from `calc-size(calc-size(auto, size * .5), size * .5)` to `calc-size(calc-size(auto, size + 100px), size * 2)`, and the `auto` size is 200px.

The first will result in a final size of 50px (200px * .5 * .5). The second will result in 600px (200px + 100px * 2). Ideally we want the halfway point of the interpolation to be halfway between these two, at 325px. But how do we represent that?

We don't get that result in the current spec text; current spec tells us to interpolate the basis and the calculation, resulting in (after simplification) `calc(calc-size(auto, size * .75 + 50px), size)`, or `200px`.

What we *want* is to produce some form where only the final calculation is what's interpolated, so we don't get the double-interpolation quadratic behavior.

A failed attempt I made just now was to allow "sequence of calculations" to be expressed directly in the syntax, but that still runs us into issues - simplifying into `calc-size(auto, size * .5, size * .5)` and `calc-size(auto, size + 100px, size * 2)` still doesn't give us a way to represent the intermediate value.

I think what we actually need *is* the ability to represent a calculation sequence as a first-class concept. Let's pretend that `calc-seq(<calc-sum>#)` exists, representing the result of resolving each item in order, and making the previous result available to the next calculation via a `result` keyword.

Then we can instead simplify the functions to `calc-size(auto, calc-seq(size * .5, result * .5))` and `calc-size(auto, calc-seq(size + 100px, result * 2))`. The interpolated value would then be `calc-size(auto, calc-seq(size * .5, result * .5) * .5 + calc-seq(size + 100px, result * 2) * .5)`.

That final calculation, then (again assuming the auto size is 200px) would be `50px * .5 + 600 * .5`, exactly the 325px we needed.

We don't *necessarily* need to make this a generic functionality; we could specialize it to calc-size() if we wanted, since we don't need it anywhere else so far. But if we eat the complexity of a calc sequence here, seems like we might as well do it generally anyway.

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10220#issuecomment-2093709872 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Friday, 3 May 2024 20:21:39 UTC