[csswg-drafts] [css-view-transitions] Behavior of calling `document.startViewTransition` synchronously more than once (#11292)

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

== [css-view-transitions] Behavior of calling `document.startViewTransition` synchronously more than once ==
Demo: https://codepen.io/bramus/pen/gOVyzjL

This demo has two successive calls to `document.startViewTransition`:

```js
document.querySelectorAll('.item label').forEach(($label) => {
 // @note: we listen on click because that happens *before* a change event
 $label.addEventListener('click', async (e) => {
  if (!document.startViewTransition) return;

  e.preventDefault();
  const $input = $label.querySelector('input');
  
  document.startViewTransition(() => {
   $input.checked = !$input.checked;
  });

  document.startViewTransition(() => {
   document.body.style.padding = `${Math.random() * 10}rem`;
  });
  
 });
});
```

When you check this in Chrome, the code from both callbacks get executed as part of the View Transition: the faux `<details>` opens/closes using an animation + it also moves around because the padding of the `<body>` was changed.

When you check this in Safari, only the code from the second callbacks gets executed as part of the View Transition: the faux `<details>` is immediately opened/closed and only moves around because the padding of the `<body>` was changed.

As [per spec](https://drafts.csswg.org/css-view-transitions-1/#ViewTransition-prepare), the second call to `document.startViewTransition` should skip any active view transition, which led me to believe Safari is doing the right thing here.

Checking things with @noamr, he [says](https://issues.chromium.org/issues/379422729#comment4) it’s racy in the spec:

> This is actually racy in the spec:
> 
> 1. const transition1 = document.startViewTransition(updateCallback1);
> 2. document.startViewTransition(updateCallback2):
>      2.1 calls transition1.skipTransition() internally
>         2.1.1 queue a task to call updateCallback1
>      2.2 wait till the next rendering steps
>          2.2.1 capture the old state
>          2.2.2 queue a task to call updateCallback2
> 
> There is no guarantee that 2.2.1 would be after/before 2.1.1. It's a race between the rendering steps and the queued update callback.

I’m not sure if an how we can solve, but I surely would love to see all implementations behave the same by having intstructions for what to do in this case baked into the spec.

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


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

Received on Thursday, 28 November 2024 15:37:12 UTC