Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interaction with Safari's back/forward previews #8333

Closed
jakearchibald opened this issue Jan 19, 2023 · 9 comments
Closed

Interaction with Safari's back/forward previews #8333

jakearchibald opened this issue Jan 19, 2023 · 9 comments
Labels
css-view-transitions-1 View Transitions; Bugs only

Comments

@jakearchibald
Copy link
Contributor

jakearchibald commented Jan 19, 2023

Both Safari iOS and Safari Desktop have a feature where you see a 'preview' of the previous history entry when you drag from the edge (iOS) or two-finger swipe (Desktop). This includes same-document traversals.

out.mp4
safari-desktop.mp4

This already causes issues in cases where developers have created their own transition. Demo: https://static-misc-3.glitch.me/basic-navigation-transition/. Here's what happens:

  1. User is on "state 2".
  2. User drags from the left, revealing a screenshot of "state 1".
  3. Navigation commits, but since it's same-document, it's still in "state 1".
  4. Developer gets a popstate event, so they begin a transition from "state 1" to "state 2", meaning it looks like things 'snap back' to "state 2".
out.mp4

It feels like we should avoid this kind of experience with view transitions (both SPA and MPA) at least.

I think a good starting point is: Is there something developers should be doing today to avoid this kind of experience in Safari? If not, we can invent something 😀

@smfr any ideas around this? It seems to be a problem in the wild https://twitter.com/ryanflorence/status/1362095580827160578

@khushalsagar
Copy link
Member

This is an issue even without View Transitions, an SPA could do custom transitions with any internal framework.

@khushalsagar khushalsagar changed the title [css-view-transitions-1] Interaction with Safari's back/forward previews Interaction with Safari's back/forward previews Jan 19, 2023
@romainmenke
Copy link
Member

romainmenke commented Jan 19, 2023

Also doesn't need to be an SPA :)

click any of big titles and then swipe for a back preview :
https://www.hugoandmarie.com/creative/

There is no way to tell Safari when it should create these previews.
So any "outro" animation will mess with it.

We never found a way to make these previews work properly and have transitions.

Screenshot 2023-01-19 at 19 12 38

@khushalsagar
Copy link
Member

khushalsagar commented Jan 20, 2023

@romainmenke, I'm able to repro the issue on the site above. Do you mind clarifying the timing of the animation with the navigation? What event do you use to trigger the animation?

I'm seeing 2 classes of problems with these default transitions. I think solving Double Transition is easier so we could start with the small API proposal for it below. @domenic @annevk thoughts?

Double Transition
The browser does a transition in response to swipe and the author (who is unaware of this transition) does a transition after. @jakearchibald's demo and the twitter thread above shows that clearly. A trivial way developers can avoid this is by being notified that there's already been a browser transition for a navigation. Something like:

window.addEventListener('popstate', (event) => {
  if (event.hasBrowserTransition) {
   navigateOnly();
    return;
  }

  navigateAndAnimate();
});

navigation.addEventListener('navigate', (event) => {
  if (event.hasBrowserTransition) {
    navigateOnly();
    return;
  }

  navigateAndAnimate();
});

Incorrect Capture
The browser captures a visual state which is inconsistent with what the user will see on back. This could be from multiple cases:

  1. An exit animation like in the comment above.
  2. Transient UI which is intentionally removed by the page. Example.
  3. User interacted with the page before navigation and a new load doesn't have the mutations in response to that interaction. Scroll restoration takes care of the common case of restoring the scroll offset but not everything. This also depends on whether the nav gets a BFCache hit.

This is harder to solve. We could add a hook where the browser informs the page that it will be captured for a preview and should set up state accordingly. But given case 3 above, it's not deterministic what the user will see at the time the browser would ideally do a capture (the last frame rendered by the outgoing page).

@romainmenke
Copy link
Member

romainmenke commented Jan 20, 2023

I'm able to repro the issue on the site above. Do you mind clarifying the timing of the animation with the navigation? What event do you use to trigger the animation?

In short :

  • user hovers a link that is "transitionable"
  • prefetch/prerender the target page
  • user clicks a link that is "transitionable"
  • play the matching outro
  • trigger the navigation

We have to be careful to undo the outro when a user navigates back but other than that it is a fairly simple setup.

Browsers avoid a flash of white in between navigations, so it appears to be seamless like an SPA transition. But it is just hover and click events.

Because this is al just hacks there is no way for Safari to "understand" that we are playing an outro. It captures the back preview when the actual navigation happens, not when the user clicks the link.

We would never implement anything like this if there was a native API for transitions of this kind. Today there is no native way.

@khushalsagar
Copy link
Member

Got it, so you consume the click to do an animation and then trigger the navigation.

We would never implement anything like this if there was a native API for transitions of this kind. Today there is no native way.

Glad to hear this. So a primitive like cross-document ViewTransitions would help. If the animation is expressed using a browser primitive, then the browser knows what to capture.

@jakearchibald
Copy link
Contributor Author

Filed whatwg/html#8782 with a proposal

@fantasai fantasai added the css-view-transitions-1 View Transitions; Bugs only label Jun 1, 2023
@khushalsagar
Copy link
Member

@fantasai This issue is still on our priority list, whatwg/html#8782 was discussed at the html triage meeting and we're waiting for feedback from other implementors.

I don't think this needs to be a blocker for VT L1 though. Interaction with UA transitions is a problem irrespective of View Transitions, since authors can create them for same-document navigations with a framework other than VT. And conversely, VT has no way of knowing if a transition is in response to a navigation or just any DOM change. Sounds reasonable?

@khushalsagar
Copy link
Member

Chatted with @fantasai offline. The solution for this problem is tracked in whatwg/html#8782 and #8747 but I'm putting this on the agenda to confirm with the group that VT L1 doesn't need to block on this.

@khushalsagar
Copy link
Member

I'll close this in favour of whatwg/html#8782 which addresses the problem described in this issue. The API addition will need to be in the html spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-view-transitions-1 View Transitions; Bugs only
Projects
None yet
Development

No branches or pull requests

4 participants