[csswg-drafts] [css-anchor-position][css-position] Fixing the animation problem (#9598)

tabatkins has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-anchor-position][css-position] Fixing the animation problem ==
Issue: Because the inset properties are four separate properties, you can't animate them "together" - instead you can animate each of the four independently, and hope that what you're expressing is reasonable for that to work. That's not always true!

For example, going from `bottom: anchor(top);` to `top: anchor(bottom);` (with the opposite inset being `auto`) will *not* animate properly - it'll be trying to interpolate `top` from `auto` to `anchor(bottom)` (which won't work), and similar for `bottom`. You *can* explicitly write a `top/bottom: 0;` in each case, which will technically animate, but not in a useful way; now, to get things to line up correctly, you'll need to specify `align-self` too:

```css
.first {
  top: 0;
  bottom: anchor(top);
  align-self: end;
}
.second {
  top: anchor(bottom);
  bottom: 0;
  align-self: start;
}
```

...and `align-self` doesn't have animation rules to smoothly animate from `start` to `end` (yet, #9556). (And even if we did, it wouldn't work quite correctly - an `align-self: start 50%;` will center in an IMCB with a top of `(0% + anchor(bottom))/2` and a bottom of `(0% + anchor(top))/2`, and that is very likely *not* halfway between its starting and ending position. In general, this sort of "interpolate a position within an interpolating range" doesn't produce a linear interpolation of the position in an absolute context; it produces a quadratic spline path instead.)

--------

So that's the issue. How do we solve it? Here's my suggestion:

1. Repurpose `inset-area`. In addition to the existing grid-based syntax, add a `[ <side-keyword> <length-percentage> ]{1,4}` production, which similarly defines a rectangle and causes `auto` insets (and `normal` self-alignment) to resolve accordingly. So `inset-area: top anchor(bottom);`, for example.
2. Change the inset-area rules so that, rather than resolving `auto` insets (and `normal` self-alignments) at computed-value time, they resolve at used-value time. This removes the ability to animate the inset properties directly from the inset-area value.
3. Instead, make `inset-area` directly animateable. Add `inset-area-mix(...)`, which represents the interpolated result between two `inset-area` values. This represents whatever insets and alignments would be required to make the position of the element interpolate smoothly between the two endpoints (rather than being a naive interpolation of edges and alignment). So long as all your actual inset properties and self-alignment properties are set to `auto`/`normal`, it'll Just Work.

I still need to give a little more thought to how the new side-based production handles alignment. In the grid syntax I can *pretend* that the default anchor is inside the containing block, so all the grid lines are correctly ordered and I can infer some positioning, but that's more difficult when the edges can indeed be misordered due to positioning. I'm pretty sure there's a good solution here, I just haven't fully worked thru it yet.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9598 using your GitHub account


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

Received on Monday, 13 November 2023 20:53:40 UTC