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

Technical review: Document cross-document view transitions #32723

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
c7dcd4e
Document cross-document view transitions
chrisdavidmills Mar 18, 2024
218ab88
Add link rel=expect explanation
chrisdavidmills Mar 18, 2024
b82a640
Update existing content to make sense for SPA and MPA transitions
chrisdavidmills Mar 19, 2024
000fa78
Add doc for @view-transition at-rule
chrisdavidmills Mar 19, 2024
429ef2f
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Mar 20, 2024
d891779
Add rel=expect content
chrisdavidmills Mar 20, 2024
30accf7
Add pagereveal and pageswap event pages
chrisdavidmills Mar 21, 2024
30eb72d
Add docs for NavigationActivation
chrisdavidmills Mar 22, 2024
a03d960
Add docs for PageRevealEvent and PageSwapEvent
chrisdavidmills Mar 22, 2024
ce1710d
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Mar 22, 2024
8b88c2a
fix folder naming issue
chrisdavidmills Mar 23, 2024
7c50ef8
Merge branch 'cross-document-view-transitions' of github.com:chrisdav…
chrisdavidmills Mar 23, 2024
3a33825
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Mar 23, 2024
dd176af
Update files/en-us/web/api/viewtransition/index.md
chrisdavidmills Mar 24, 2024
175a58b
Improvements to demo links and explanations, make event objects part …
chrisdavidmills Mar 26, 2024
a55a815
add PageRevealEvent and PageSwapEvent to HTML DOM landing page
chrisdavidmills Mar 26, 2024
4224491
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Mar 28, 2024
8640c51
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Apr 12, 2024
8f3dfaa
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Apr 12, 2024
290489c
Fixes for bramus and noamr review comments
chrisdavidmills Apr 12, 2024
0973ce2
Update some details of rel=expect
chrisdavidmills Apr 24, 2024
79b7ca3
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Apr 24, 2024
3a50822
Add note back in that was recently added to main
chrisdavidmills Apr 24, 2024
2afc294
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills May 24, 2024
4f19f17
Latest fixes to review comments
chrisdavidmills May 24, 2024
b9a7530
Update files/en-us/web/html/attributes/rel/index.md
chrisdavidmills May 24, 2024
9e1d074
Update files/en-us/web/api/navigationactivation/index.md
chrisdavidmills May 24, 2024
7fe0eaf
Update files/en-us/web/api/window/pageswap_event/index.md
chrisdavidmills May 24, 2024
0b142e5
Update files/en-us/web/api/window/pageswap_event/index.md
chrisdavidmills May 24, 2024
c894f7b
Update files/en-us/web/api/window/pageswap_event/index.md
chrisdavidmills May 24, 2024
a768586
Update files/en-us/web/api/pagerevealevent/index.md
chrisdavidmills May 24, 2024
d788f87
Update files/en-us/web/api/navigationactivation/index.md
chrisdavidmills May 24, 2024
03dccd3
Update files/en-us/web/api/pagerevealevent/index.md
chrisdavidmills May 24, 2024
6ad60a1
Update files/en-us/web/api/window/pageswap_event/index.md
chrisdavidmills May 24, 2024
45fa318
Update files/en-us/web/api/pagerevealevent/index.md
chrisdavidmills May 24, 2024
be95206
Update files/en-us/web/api/navigationactivation/index.md
chrisdavidmills May 24, 2024
bb868a0
Update files/en-us/web/api/pageswapevent/index.md
chrisdavidmills May 24, 2024
4191156
Update files/en-us/web/api/pageswapevent/index.md
chrisdavidmills May 24, 2024
6faaebb
Update files/en-us/web/api/pageswapevent/index.md
chrisdavidmills May 24, 2024
d6d62ed
Update files/en-us/web/api/pageswapevent/index.md
chrisdavidmills May 24, 2024
c4ef9cc
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
781ad75
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
220f138
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
fdd0cd2
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
d557f5c
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
ecdc3d3
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
c7fa835
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
c203f38
Update files/en-us/web/api/window/pagereveal_event/index.md
chrisdavidmills May 24, 2024
3022d22
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
f757a64
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
1d2e5d3
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills May 24, 2024
7f84898
Update files/en-us/web/api/window/pagereveal_event/index.md
chrisdavidmills May 24, 2024
c97f061
Update files/en-us/web/api/window/pagereveal_event/index.md
chrisdavidmills May 24, 2024
632d453
Merge branch 'main' into cross-document-view-transitions
chrisdavidmills Jun 12, 2024
64b2e7e
Fixes for bramus tech review comments
chrisdavidmills Jun 12, 2024
0aef236
Update files/en-us/web/api/pageswapevent/index.md
chrisdavidmills Jun 13, 2024
34fadad
Update files/en-us/web/api/pageswapevent/index.md
chrisdavidmills Jun 13, 2024
afcc431
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills Jun 13, 2024
4913b12
Update files/en-us/web/api/view_transitions_api/using/index.md
chrisdavidmills Jun 13, 2024
cc29537
Update files/en-us/web/api/window/pageswap_event/index.md
chrisdavidmills Jun 13, 2024
e3ead76
Update files/en-us/web/api/window/pageswap_event/index.md
chrisdavidmills Jun 13, 2024
6fff811
A few more fixes
chrisdavidmills Jun 13, 2024
aec4da8
Clarify bfcache notes and add explanation about bfcache conflict issue
chrisdavidmills Jun 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 30 additions & 21 deletions files/en-us/web/api/navigationactivation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ browser-compat: api.NavigationActivation

The **`NavigationActivation`** interface of the [Navigation API](/en-US/docs/Web/API/Navigation_API) represents a recent cross-document navigation. It contains the navigation type and outgoing and inbound document history entries.

This object is accessed via the {{domxref("PageSwapEvent.activation")}} and {{domxref("Navigation.activation")}} properties.
This object is accessed via the {{domxref("PageSwapEvent.activation")}} and {{domxref("Navigation.activation")}} properties. Note that, in each case, the `NavigationActivation` represents a different navigation:

- `Navigation.activation` represents information about the navigation to the current page.
- `PageSwapEvent.activation` represents information about the navigation to the next page.

## Instance properties

Expand All @@ -34,36 +37,42 @@ window.addEventListener("pagereveal", async (e) => {
const fromUrl = new URL(navigation.activation.from.url);
const currentUrl = new URL(navigation.activation.entry.url);

// Only transition to/from same basePath
// ~> SKIP!
if (!fromUrl.pathname.startsWith(basePath)) {
e.viewTransition.skipTransition();
}

// Went from profile page to homepage
// ~> Set VT names on the relevant list item
if (isProfilePage(fromUrl) && isHomePage(currentUrl)) {
const profile = extractProfileNameFromUrl(fromUrl);

setTemporaryViewTransitionNames(
[
[document.querySelector(`#${profile} span`), "name"],
[document.querySelector(`#${profile} img`), "avatar"],
],
e.viewTransition.ready,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#${profile} span`).style.viewTransitionName =
"name";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
document.querySelector(`#${profile} span`).style.viewTransitionName =
"none";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"none";
}

// Went to profile page
// ~> Set VT names on the main title and image
if (isProfilePage(currentUrl)) {
setTemporaryViewTransitionNames(
[
[document.querySelector(`#detail main h1`), "name"],
[document.querySelector(`#detail main img`), "avatar"],
],
e.viewTransition.ready,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#detail main h1`).style.viewTransitionName =
"name";
document.querySelector(`#detail main img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
document.querySelector(`#detail main h1`).style.viewTransitionName =
"none";
document.querySelector(`#detail main img`).style.viewTransitionName =
"none";
}
}
});
Expand Down
46 changes: 26 additions & 20 deletions files/en-us/web/api/pagerevealevent/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,36 +48,42 @@ window.addEventListener("pagereveal", async (e) => {
const fromUrl = new URL(navigation.activation.from.url);
const currentUrl = new URL(navigation.activation.entry.url);

// Only transition to/from same basePath
// ~> SKIP!
if (!fromUrl.pathname.startsWith(basePath)) {
e.viewTransition.skipTransition();
}

// Went from profile page to homepage
// ~> Set VT names on the relevant list item
if (isProfilePage(fromUrl) && isHomePage(currentUrl)) {
const profile = extractProfileNameFromUrl(fromUrl);

setTemporaryViewTransitionNames(
[
[document.querySelector(`#${profile} span`), "name"],
[document.querySelector(`#${profile} img`), "avatar"],
],
e.viewTransition.ready,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#${profile} span`).style.viewTransitionName =
"name";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
document.querySelector(`#${profile} span`).style.viewTransitionName =
"none";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"none";
}

// Went to profile page
// ~> Set VT names on the main title and image
if (isProfilePage(currentUrl)) {
setTemporaryViewTransitionNames(
[
[document.querySelector(`#detail main h1`), "name"],
[document.querySelector(`#detail main img`), "avatar"],
],
e.viewTransition.ready,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#detail main h1`).style.viewTransitionName =
"name";
document.querySelector(`#detail main img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
document.querySelector(`#detail main h1`).style.viewTransitionName =
"none";
document.querySelector(`#detail main img`).style.viewTransitionName =
"none";
}
}
});
Expand Down
46 changes: 26 additions & 20 deletions files/en-us/web/api/pageswapevent/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,36 +36,42 @@ window.addEventListener("pageswap", async (e) => {
: null;
const targetUrl = new URL(e.activation.entry.url);

// Only transition to same basePath
// ~> SKIP!
if (!targetUrl.pathname.startsWith(basePath)) {
e.viewTransition.skipTransition();
}

// Going from profile page to homepage
// ~> The big img and title are the ones!
if (isProfilePage(currentUrl) && isHomePage(targetUrl)) {
setTemporaryViewTransitionNames(
[
[document.querySelector(`#detail main h1`), "name"],
[document.querySelector(`#detail main img`), "avatar"],
],
e.viewTransition.finished,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#detail main h1`).style.viewTransitionName =
"name";
document.querySelector(`#detail main img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
document.querySelector(`#detail main h1`).style.viewTransitionName =
"none";
document.querySelector(`#detail main img`).style.viewTransitionName =
"none";
}

// Going to profile page
// ~> The clicked items are the ones!
if (isProfilePage(targetUrl)) {
const profile = extractProfileNameFromUrl(targetUrl);

setTemporaryViewTransitionNames(
[
[document.querySelector(`#${profile} span`), "name"],
[document.querySelector(`#${profile} img`), "avatar"],
],
e.viewTransition.finished,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#${profile} span`).style.viewTransitionName =
"name";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
document.querySelector(`#${profile} span`).style.viewTransitionName =
"none";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"none";
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/view_transitions_api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ status:
- experimental
browser-compat:
- api.Document.startViewTransition
- api.ViewTransition
- css.at-rules.view-transition
spec-urls: https://drafts.csswg.org/css-view-transitions/
---

Expand Down
115 changes: 54 additions & 61 deletions files/en-us/web/api/view_transitions_api/using/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ To handle creating the outbound and inbound transition animations, the API const
└─ ::view-transition-new(root)
```

> **Note:** a {{cssxref("::view-transition-group")}} is created for every view-transition-name that was captured?
> **Note:** a {{cssxref("::view-transition-group")}} subtree is created for every captured `view-transition-name`.

In the case of same-document transitions (SPAs), the pseudo-element tree is made available in the document. In the case of cross-document transitions (MPAs), the pseudo-element tree is made available in the destination document only.

The most interesting parts of the tree structure are as follows:

- {{cssxref("::view-transition")}} is the root of view transitions overlay, which contains all view transition snapshot groups and sits over the top of all other page content.
- A {{cssxref("::view-transition-group")}} acts as a container for each view transition snapshot group. The `root` argument specifies the default snapshot group — the view transition animation will apply to the `:root` element and all elements nested within it.
- A {{cssxref("::view-transition-group")}} acts as a container for each view transition snapshot group. The `root` argument specifies the default snapshot group — the view transition animation will apply to the snapshot whose `view-transition-name` is `root`.
> **Note:** It is possible to target different DOM elements with different custom view transition animations by setting a different {{cssxref("view-transition-name")}} on each one. In such cases, a `::view-transition-group` is created for each one. See [Different animations for different elements](#different_animations_for_different_elements) for an example.
- {{cssxref("::view-transition-old")}} targets the static snapshot of the old page element, and {{cssxref("::view-transition-new")}} targets the live snapshot of the new page element. Both of these render as replaced content, in the same manner as an {{htmlelement("img")}} or {{htmlelement("video")}}, meaning that they can be styled with handy properties like {{cssxref("object-fit")}} and {{cssxref("object-position")}}.

Expand Down Expand Up @@ -367,36 +367,42 @@ window.addEventListener("pageswap", async (e) => {
: null;
const targetUrl = new URL(e.activation.entry.url);

// Only transition to same basePath
// ~> SKIP!
if (!targetUrl.pathname.startsWith(basePath)) {
e.viewTransition.skipTransition();
}

// Going from profile page to homepage
// ~> The big img and title are the ones!
if (isProfilePage(currentUrl) && isHomePage(targetUrl)) {
setTemporaryViewTransitionNames(
[
[document.querySelector(`#detail main h1`), "name"],
[document.querySelector(`#detail main img`), "avatar"],
],
e.viewTransition.finished,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#detail main h1`).style.viewTransitionName =
"name";
document.querySelector(`#detail main img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
document.querySelector(`#detail main h1`).style.viewTransitionName =
"none";
document.querySelector(`#detail main img`).style.viewTransitionName =
"none";
}

// Going to profile page
// ~> The clicked items are the ones!
if (isProfilePage(targetUrl)) {
const profile = extractProfileNameFromUrl(targetUrl);

setTemporaryViewTransitionNames(
[
[document.querySelector(`#${profile} span`), "name"],
[document.querySelector(`#${profile} img`), "avatar"],
],
e.viewTransition.finished,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#${profile} span`).style.viewTransitionName =
"name";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
document.querySelector(`#${profile} span`).style.viewTransitionName =
"none";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"none";
}
}
});
Expand All @@ -414,60 +420,47 @@ window.addEventListener("pagereveal", async (e) => {
const fromUrl = new URL(navigation.activation.from.url);
const currentUrl = new URL(navigation.activation.entry.url);

// Only transition to/from same basePath
// ~> SKIP!
if (!fromUrl.pathname.startsWith(basePath)) {
e.viewTransition.skipTransition();
}

// Went from profile page to homepage
// ~> Set VT names on the relevant list item
if (isProfilePage(fromUrl) && isHomePage(currentUrl)) {
const profile = extractProfileNameFromUrl(fromUrl);

setTemporaryViewTransitionNames(
[
[document.querySelector(`#${profile} span`), "name"],
[document.querySelector(`#${profile} img`), "avatar"],
],
e.viewTransition.ready,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#${profile} span`).style.viewTransitionName =
"name";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
document.querySelector(`#${profile} span`).style.viewTransitionName =
"none";
document.querySelector(`#${profile} img`).style.viewTransitionName =
"none";
}

// Went to profile page
// ~> Set VT names on the main title and image
if (isProfilePage(currentUrl)) {
setTemporaryViewTransitionNames(
[
[document.querySelector(`#detail main h1`), "name"],
[document.querySelector(`#detail main img`), "avatar"],
],
e.viewTransition.ready,
);
// Set view-transition-name values on the elements to animate
document.querySelector(`#detail main h1`).style.viewTransitionName =
"name";
document.querySelector(`#detail main img`).style.viewTransitionName =
"avatar";

// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
document.querySelector(`#detail main h1`).style.viewTransitionName =
"none";
document.querySelector(`#detail main img`).style.viewTransitionName =
"none";
}
}
});
```

The `setTemporaryViewTransitionNames()` user-defined function is used repeatedly in this code. This looks like so:

```js
const setTemporaryViewTransitionNames = async (entries, vtPromise) => {
// Apply a custom view transition to each element passed into the function
for (const [$el, name] of entries) {
$el.style.viewTransitionName = name;
}

// Await the view transition promise passed into the function, e.g. ready or finished
await vtPromise;

// Remove the custom view transition from each element passed into the function
for (const [$el, name] of entries) {
$el.style.viewTransitionName = "";
}
};
```

## Stabilizing page state to make cross-document transitions consistent

Before running a cross-document transition, you ideally want to wait until the state of the page stabilizes, relying on [render blocking](/en-US/docs/Glossary/Render_blocking) to ensure that:
Expand Down
4 changes: 2 additions & 2 deletions files/en-us/web/api/viewtransition/skiptransition/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ transition.skipTransition();
```js
// Fired on the current (outgoing) page
document.addEventListener("pageswap", (event) => {
event.viewTransition.skipTransition();
event.viewTransition?.skipTransition();
});

// Fired on the destination (inbound) page
document.addEventListener("pagereveal", (event) => {
event.viewTransition.skipTransition();
event.viewTransition?.skipTransition();
});
```

Expand Down
Loading
Loading