Re: [csswg-drafts] [css-animations] Resolving dependencies in keyframes (#5125)

> Thank you @birtles! This means that current state of affairs is that G-β is supposed to be the correct behavior? If I'm not mistaken, this is approximately the same as option 3 here. (Right?)

Right.

> But "just" using computed values doesn't work either, does it?

Right, I think we need to distinguish between what the browser internally stores and what `getKeyframes()` returns.

So it's fine to internally retain the `em` units but then resolve them to `px` when generating the result for `getKeyframes()`.

> ...And at the same time, there's a transition on `font-size` that moves from `10px` to `20px` in the same time period. The computed value of `font-size` is then determined by the value the transition adds to the cascade. Is the idea that getKeyframes should return (an object equivalent to):
> 
> ```
> @keyframes test {
>   from { width: 10px; }
>   to { width: 40px; }
> }
> ```

No, you'd get a different object depending on when you called `getKeyframes()`. At the start you'd get:

```js
{
  offset: 0,
  width: '10px'
},
{
  offset: 1,
  width: '20px',
}
```

and at the end you'd get:

```js
{
  offset: 0,
  width: '20px'
},
{
  offset: 1,
  width: '40px',
}
```

That means that round-tripping the result of `getKeyframes()` to `setKeyframes()` loses information but I think it's the best we can do given the mismatch between CSS syntax and the simple JS notation we have. If you want to retain em units (or variable references for that matter), you need to either update the `@keyframes` rule or set the `em` units yourself.

Somewhere I wrote a long comment about some of the edge cases that make this expansion necessary but I can't find it now. I think though it's particularly cases like:

```css
  :root {
    --two-values: 10em 20em;
  }
  body {
    font-size: 10px;
  }
  @keyframes a {
    to {
      margin: var(--two-values);
      margin-right: 30em;
      margin-right: 40em;
    }
    to {
      margin-left: 50em;
      margin-inline: 60em;
      margin-inline-start: 70em;
    }
  }
```

The full-fidelity representation of that using Web animations keyframe objects might be something like:

```js
{
  offset: 1,
  margin: 'var(--two-values)',
  marginInline: '60em',
  marginInlineStart: '70em'
}
```

but when the writing-mode changes it might be:

```js
{
  offset: 1,
  margin: 'var(--two-values)',
  marginInline: '60em',
  marginInlineStart: '70em',
  marginRight: '40em',
  marginLeft: '50em'
}
```

(And we can't unconditionally include `marginRight` and `marginLeft` since they will clobber the other values.)

Simply trying to keep track of which properties clobber which is difficult in light of overlapping keyframes and shorthands and logical properties so it's easiest if you can expand to physical longhand properties.

But then that becomes complicated because until you expand variables, you don't know where properties will get their values from. Hence why we ended up just expanding everything to physical longhand properties with computed values when generating keyframes from `getKeyframes()`.

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

Received on Tuesday, 2 June 2020 03:01:22 UTC