#851: Cross-document View Transitions API

Visit on Github.

Opened May 30, 2023

こんにちは TAG-さん!

I'm requesting a TAG review of Cross-document View Transitions API (css-view-transitions-2).

Cross-document transitions are an extension to same-document transitions, adding the semantics necessary to display transitions when navigating across documents.

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • The group where the incubation/design work on this is being done (or is intended to be done in the future):
  • The group where standardization of this work is intended to be done ("unknown" if not known):
  • Existing major pieces of multi-stakeholder review or discussion of this design:
  • Major unresolved issues with or opposition to this design:
  • This work is being funded by:

You should also know that...

See design review for same-document transitions: #748

We'd prefer the TAG provide feedback as (please delete all but the desired option):

☂️ open a single issue in our GitHub repo for the entire review


CAREFULLY READ AND DELETE CONTENT BELOW THIS LINE BEFORE SUBMITTING

Please preview the issue and check that the links work before submitting.

In particular:

  • if anything links to a URL which requires authentication (e.g. Google document), please make sure anyone with the link can access the document. We would prefer public documents though, since we work in the open.

¹ For background, see our explanation of how to write a good explainer. We recommend the explainer to be in Markdown.

² Even for early-stage ideas, a Security and Privacy questionnaire helps us understand potential security and privacy issues and mitigations for your design, and can save us asking redundant questions. See https://www.w3.org/TR/security-privacy-questionnaire/.

Discussions

Comment by @khushalsagar May 30, 2023 (See Github)

@atanassov @LeaVerou FYI.

Discussed Jul 1, 2023 (See Github)

Lea: First time we look at this.

  • Mozilla is positive, no response from WebKit.
  • Requires both opt-in from both pages, AND same-origin.
  • Opt-in is HTML, for a CSS feature, which seems suboptimal. CSS proposal may be better, though not colloquial to CSS as is.
  • Opt-in might be too general, aren't there use cases where you only want to opt-in more conditionally? [they said this is still fleshed out]
  • +1 for Declarative API!
  • A bit unclear what happens if both documents opt in, but there is no JS to customize the transition.
  • A bit worried about the user experience on slow networks. Does the transition abort at some point?
  • sticky transition bugs: if some JS code sets the transition params, and a different part of the code calls event.preventDefault()?
<blockquote>

We were happy to see cross-stakeholder support, though we'd like to see WebKit’s position as well. We also liked the secure-first design, with two-way opt-in and a same-origin restriction. Is cross-origin a non-goal because there are few use cases for it, or because you are not confident in the security of a cross-origin opt-in?

It seems a little inflexible to have the opt-in be HTML (as you point out); A CSS mechanism would indeed be preferable, though the proposed syntax is not idiomatic to CSS, since there is no precedent of @-rules that take values (this does not necessarily mean this is a bad idea, but when something creates a new precedent, we should spend extra effort to make sure there is no alternative design that is more consistent with the existing Web Platform without sacrificing usability.

Props for a declarative-first API too!

We had a few questions, that we didn't find the answers to in the explainer:

  • What happens when both documents opt in, but there is no JS to customize the transition?
  • What is the user experience on a very slow connection? We see there is an implementation-defined timeout, we do worry that clicking on a link, then nothing happening, then suddenly a transition could result in jarring user experience.
  • What is the user experience if one part of the code customizes the transition parameters, and another calls event.preventDefault() so the navigation never actually happens?
</blockquote>

Rossen: comment looks great. concern with slow connection - how does it differ?

Lea: transition need to wait... how long does it wait... what happens? From user's pov?

Rossen: looks at spec. In section 7.4 - a quick algo - 4 main steps -

Rossen: proceed with the comment - lea's point about the slow connectiom might be answered by the timeout... which cancels the transition.

Discussed Jul 1, 2023 (See Github)

[long reply to Lea, plus an ED is out]

bump to plenary

Discussed Jul 1, 2023 (See Github)

Dan: Looking at new draft spec

Lea: Cross-fade? what happens?

Lea: "the transition happens" - what happens? [see comment(https://github.com/w3ctag/design-reviews/issues/851#issuecomment-1618916752)

Lea: what happens in slow connection... timeouts... not an ideal user experience. Response is "because it's same origin it shouldn't take that long" - not a given that it's tested for slow connections and wifi...

Dan: +1

Rossen: i think most of the questions are answered OK... Even for the slow connection.. I think it's a valid point. You control the to and from experience - you can have whatever logic you want as a developer... You can do all of this because it's the same origin...

Lea: still unclear - how do you prevent a pause after clicking on a link? Are you able to detect if the user is on a slow connection? Proposed media query...

Rossen: maybe start a timer and...? would the browser UX be engaged in this case? so the browser has a spinner... That's not gonna be engaged at all...

Lea: I would expect the browser spinner would start when you click on the link. Maybe that's enough signal that something's happening. Just want to make sure users on slow connections don't sit there with no feedback.

Rossen: I think that wouldn't happen.

Dan: agree this should be in the spec - right now it doesn't mention "slow"...

lea to leave feedback

Rossen: a section on security considerations -- "concern around safety of 3rd party css - however as a general rule 3rd party css should come from trusted sources" -- that's ... nothing happens as a general rule on the web. We need a threat model to understand timing-related attack vectors that weren't previously exposed.

Dan: could we ask them to do a more rigorous security review?

Rossen: same origin nav could happen between a 3rd party re-direct... This can cause a (minor) situation... unexpected transition... I think this section needs to be ... strengthened ... Same origin without cross-origin re-directs.. that's fine. Other 2 places this is spelled out - in the algo for setting up cross origin view transition...

Rossen: I'm luke-warm. They did spell it out and call it out.

Discussed Jul 1, 2023 (See Github)

Propose close. draft text:

`Looking at the issue @hober during our virtual f2f and following all threads, we agree with @LeaVerou and are happy to resolve it. Looking forward to seeing this feature adopted and in use. Thank you for flying TAG.

@LeaVerou please close once you have a chance to confirm your concerns are addressed.`

Comment by @LeaVerou Jul 3, 2023 (See Github)

Hi @noamr!

We were happy to see cross-stakeholder support, though we'd like to see WebKit’s position as well. We also liked the secure-first design, with two-way opt-in and a same-origin restriction. Is cross-origin a non-goal because there are few use cases for it, or because you are not confident in the security of a cross-origin opt-in?

It seems a little inflexible to have the opt-in be HTML (as you point out); A CSS mechanism would indeed be preferable, though the proposed syntax is not idiomatic to CSS, since there is no precedent of @-rules that take values (this does not necessarily mean this is a bad idea, but when something creates a new precedent, we should spend extra effort to make sure there is no alternative design that is more consistent with the existing Web Platform without sacrificing usability.

Props for a declarative-first API too!

We had a few questions, that we didn't find the answers to in the explainer:

  • What happens when both documents opt in, but there is no JS to customize the transition?
  • What is the user experience on a very slow connection? We see there is an implementation-defined timeout, we do worry that clicking on a link, then nothing happening, then suddenly a transition could result in jarring user experience.
  • What is the user experience if one part of the code customizes the transition parameters, and another calls event.preventDefault() so the navigation never actually happens?
Comment by @noamr Jul 3, 2023 (See Github)

Hi @noamr!

Hi @LeaVerou, thanks for reviewing! Some answers inline.

We were happy to see cross-stakeholder support, though we'd like to see WebKit’s position as well. We also liked the secure-first design, with two-way opt-in and a same-origin restriction. Is cross-origin a non-goal because there are few use cases for it, or because you are not confident in the security of a cross-origin opt-in?

We see same-site cross-origin as a potential future enhancement. And even that is not devoid of security (and other) issues. The main use case we heard from partners is around same-site, e.g. landing.example.com transitioning to app.example.com. Also, see one of the answers below: to make these transitions work well, in most cases both "sides" need to be coordinated with each other. Same-origin or same-site gives us a hint that there's some degree of coordination.

All that said, who knows what the future holds. It's mainly a non-goal for now to allow us to focus on what we know are important and feasible use-cases.

It seems a little inflexible to have the opt-in be HTML (as you point out); A CSS mechanism would indeed be preferable, though the proposed syntax is not idiomatic to CSS, since there is no precedent of @-rules that take values (this does not necessarily mean this is a bad idea, but when something creates a new precedent, we should spend extra effort to make sure there is no alternative design that is more consistent with the existing Web Platform without sacrificing usability.

We're thinking the same... See proposed update to this explainer basically it would look more like @auto-view-transitions { same-origin: enable }

or some such, which would be consistent with font-face and page rules. Happy to discuss the syntax with you, TAG, and the CSSWG and I'm sure we'll find the right syntax.

Props for a declarative-first API too!

We had a few questions, that we didn't find the answers to in the explainer:

  • What happens when both documents opt in, but there is no JS to customize the transition?

The transition happens, no need for JS. The JS API is useful for:

  • observing whether there was a transition
  • Skipping the transition
  • Animating the transition's pseudo elements with the web animation API

But it's by no means necessary for the common case.

  • What is the user experience on a very slow connection? We see there is an implementation-defined timeout, we do worry that clicking on a link, then nothing happening, then suddenly a transition could result in jarring user experience.

This is another reason why this would be challenging in a cross-origin setting. It is indeed a possible scenario, however in a same-app environment (which is currently same-origin) the developer can mitigate it, deciding when to opt-in to these transitions and so forth.

The context where we see people using this is an "MPA", where the user journey in the entire app, across documents, is tested by the developer.

  • What is the user experience if one part of the code customizes the transition parameters, and another calls event.preventDefault() so the navigation never actually happens?

You mean if the old document starts the transition and the new document skips it? The moment the transition is skipped we'd render the new document's "final" (post-transition) state. This is not different from skipping a same-document transition.

Comment by @khushalsagar Jul 4, 2023 (See Github)

Some details to add to @noamr's response.

What happens when both documents opt in, but there is no JS to customize the transition?

Btw, you can see this in action on a prototype in Chrome by turning on chrome://flags/#view-transition-on-navigation. Transitions occur for any same-origin navigation where both Documents have the meta tag to opt-in. The opt-in syntax aside, transitions work using the same declarative method of adding view-transition-names to elements and the root has a name by default because of UA styles. So if a new Document has the same transition irrespective of the old Document in the navigation, transitions can be done completely declaratively.

What is the user experience on a very slow connection? We see there is an implementation-defined timeout, we do worry that clicking on a link, then nothing happening, then suddenly a transition could result in jarring user experience.

The old Document remains active and animating until the browser gets a response from the server. For example, when the user clicks a link they usually see some browser UI indicating that the navigation was initiated. The user sees content animating and they can scroll around until the browser receives a response, at which point the old Document is unloaded to be replaced by the new Document.

The flow remains exactly the same until the browser receives a response. But the browser caches a snapshot of the old Document before unloading it (or placing it in BFCache). Then there is a wait to stream in the new Document + sub-resources before the transition can start, which builds on top of render-blocking. Render-blocking already has a timeout associated with it. We don't abort the transition if the timeout is hit for any sub-resource so devs have the option to design their own fallback (one of which can be aborting the transition).

Comment by @khushalsagar Jul 14, 2023 (See Github)

Heads up, an Editor's draft for the spec is here. Would appreciate if you can consider it for the review.

Comment by @LeaVerou Jul 24, 2023 (See Github)

Hi @noamr and @khushalsagar ,

We looked at this during a breakout today.

A few clarifications about my earlier comments:

On no JS used: We're still unclear on what happens if no JS is used, from the user’s point of view. What transition happens? Like, is it a cross-fade? Something else?

It is indeed a possible scenario, however in a same-app environment (which is currently same-origin) the developer can mitigate it, deciding when to opt-in to these transitions and so forth.

Detecting a slow network is notoriously difficult (and not really black & white, you may have had a perfectly fine connection until now), so I don't think the API should depend on it for a baseline decent end-user experience.

On that note, it would be good if the CSS code to opt-in to this can be nested within media queries (e.g. see prefers-reduced-data and prefers-reduced-motion which authorrs may want to take into account). I suspect this is already possible, just bringing it up in case.

The old Document remains active and animating until the browser gets a response from the server. For example, when the user clicks a link they usually see some browser UI indicating that the navigation was initiated. The user sees content animating and they can scroll around until the browser receives a response, at which point the old Document is unloaded to be replaced by the new Document.

That’s promising! Though in slow connections the time from receiving a response to actually being able to animate to the new document can still be fairly long. But if the user perceives it as just slightly longer loading times, I guess that's not a huge issue.

It may be a good idea to advise UAs to start their loading UI when the navigation starts, so that the user does get some feedback that something is happening (possibly in a non-normative note).

You mean if the old document starts the transition and the new document skips it? The moment the transition is skipped we'd render the new document's "final" (post-transition) state. This is not different from skipping a same-document transition.

I meant if the navigation doesn't happen at all because the event was cancelled.

Comment by @khushalsagar Jul 25, 2023 (See Github)

On no JS used: We're still unclear on what happens if no JS is used, from the user’s point of view. What transition happens? Like, is it a cross-fade? Something else?

If the author doesn't provide any JS or CSS, i.e. the only addition to the Document is the opt-in, there will be a cross-fade from UA style rules. But customization can be done using CSS.

Load https://valuable-vigorous-sailor.glitch.me/index.html on chrome canary with chrome://flags/#view-transition-on-navigation enabled. The header stays in position (because it has a view-transition-name) and the root does a slide + fade animation provided via author CSS.

Our goal is to ensure that simple customization can be purely declarative. But if you need something more complicated, like navigating from a list to the details page of a list item, it requires script. Since the author needs to add a view-transition-name to the list item clicked by the user. We do want to make this case declarative eventually. The long term thinking for this is in https://github.com/w3c/csswg-drafts/issues/8209 and https://github.com/w3c/csswg-drafts/issues/8925, we've scoped it out for now.

Detecting a slow network is notoriously difficult (and not really black & white, you may have had a perfectly fine connection until now), so I don't think the API should depend on it for a baseline decent end-user experience.

That's a fair point. The spec can add a recommendation for UAs, something like: "The UA should skip the transition if there is a significant delay between when the navigation was initiated and when the new Document is no longer render-blocked". The precise threshold for skipping can be left to the UA?

On that note, it would be good if the CSS code to opt-in to this can be nested within media queries (e.g. see prefers-reduced-data and prefers-reduced-motion which authorrs may want to take into account). I suspect this is already possible, just bringing it up in case.

+1, media-query support is fundamental to the CSS syntax. Both for the exiting query for prefers-reduced-motion and our long term thinking of adding media queries to allow customization based on the old/new Document URL (see https://github.com/w3c/csswg-drafts/issues/8925).

On that note, we had a discussion today about the ordering subtlety with media queries. For example, if the author CSS is as follows:

@media (prefers-reduced-motion) {
  @view-transitions {
    navigation-trigger: cross-document;
  }
}

@view-transitions {
  navigation-trigger: cross-document;
}

Then the media-query declaration would be a no-op since the second rule would win. This is because media queries by design don't add any specificity. We were wondering whether we should have a bespoke syntax to add specificity (instead of media queries) for customizing based on old/new Document URLs. Doesn't seem worth the complexity since authors will have to ensure correct ordering for other queries like prefers-reduced-motion anyway. Open to any suggestions here.

It may be a good idea to advise UAs to start their loading UI when the navigation starts, so that the user does get some feedback that something is happening (possibly in a non-normative note).

Sure. FWIW that's what Chrome is doing but we can add a non-normative note as a recommendation to UAs.

I meant if the navigation doesn't happen at all because the event was cancelled.

Ah ok. If the navigation is cancelled (script cancelled it, the user hit stop, there was a 204 response), then no transition occurs. On the old Document the only customization an author can do is which elements get a view-transition-name. So if some part of code added the names, but another part of code cancels the navigation, those names will not be used for anything until there is a transition trigger.

Comment by @LeaVerou Jul 26, 2023 (See Github)

Hi @khushalsagar,

Thanks for your response! I cannot speak for the rest of the TAG before discussing it again, but all sounds good to me.

On that note, we had a discussion today about the ordering subtlety with media queries. For example, if the author CSS is as follows:

@media (prefers-reduced-motion) {
  @view-transitions {
    navigation-trigger: none;
  }
}

@view-transitions {
  navigation-trigger: cross-document;
}

Then the media-query declaration would be a no-op since the second rule would win. This is because media queries by design don't add any specificity. We were wondering whether we should have a bespoke syntax to add specificity (instead of media queries) for customizing based on old/new Document URLs. Doesn't seem worth the complexity since authors will have to ensure correct ordering for other queries like prefers-reduced-motion anyway. Open to any suggestions here.

I suspect there's a mistake in this example, since both declarations are identical?

This sounds like an issue to bring up with the CSS WG. FWIW it sounds like this may be adding to the pile of use cases for a selector that represents the document itself.

Comment by @khushalsagar Jul 26, 2023 (See Github)

I suspect there's a mistake in this example, since both declarations are identical?

Oops, my bad. It was supposed to be:

@media (prefers-reduced-motion) {
  @view-transitions {
    navigation-trigger: none;
  }
}

@view-transitions {
  navigation-trigger: cross-document;
}

This sounds like an issue to bring up with the CSS WG.

Sounds good. We'll be discussing the new at-rule with the group soon, will bring it up then.

Comment by @atanassov Aug 2, 2023 (See Github)

Looking at the issue @hober during our virtual f2f and following all threads, we agree with @LeaVerou and are happy to resolve it. Looking forward to seeing this feature adopted and in use. Thank you for flying TAG.

@LeaVerou please close once you have a chance to confirm your concerns are addressed.

Comment by @bokand Sep 28, 2023 (See Github)

Hello TAG!

We're planning to ship the reveal event (though naming is TBD) separately, ahead of the larger cross-document view transition API - naming and semantics have been well debated in https://github.com/whatwg/html/issues/9315.

We're wondering if the review here was sufficient for TAG purposes or if you'd prefer we file a new review issue to look specifically at the event.

@LeaVerou (for visibility)

Comment by @bokand Oct 20, 2023 (See Github)

Friendly ping - @LeaVerou @atanassov @hober

Comment by @bokand Jan 11, 2024 (See Github)

FYI: we're getting ready to ship the pagereveal event, separately from the reset of cross-document view-transitions. I haven't heard back about my question above.

@LeaVerou @atanassov @hober - Given it's a fairly minor piece and has had vigorous discussion in whatwg/html#9315 I'm inclined to think this doesn't need a TAG review separate from this issue but please chime in if you disagree and I can file a separate review. Thanks!

Comment by @khushalsagar Feb 2, 2024 (See Github)

Hello again!

Similar to reveal, we're working on specifying the conceal event which is a dependency for cross-document View Transitions but can be implemented and shipped independently of the broader feature. Here's pointers to the documentation for the event:

Explainer: https://github.com/WICG/view-transitions/blob/main/cross-doc-explainer.md#pageconceal Issue: https://github.com/whatwg/html/issues/9702 Spec PR: https://github.com/whatwg/html/pull/10002

Please let me know if you'd prefer a separate TAG review for this event.

Comment by @miketaylr Mar 1, 2024 (See Github)

FYI, the event has been renamed pageswap: https://github.com/WICG/view-transitions/blob/main/cross-doc-explainer.md#pageswap

Comment by @khushalsagar Mar 12, 2024 (See Github)

Another fyi, we're proposing a minor change to pageswap semantics: https://github.com/whatwg/html/issues/10196.