Skip to content

View Transitions

In one line: document.startViewTransition() captures a snapshot of the old DOM, lets you update the DOM, then automatically animates between the two — and @view-transition extends the same mechanism to cross-page navigations.

Call document.startViewTransition(callback) to animate a DOM update:

document.startViewTransition(() => {
// Update the DOM here — swap content, toggle classes, etc.
updateDOM();
});

The browser automatically:

  1. Captures a snapshot of the current (“old”) visual state.
  2. Runs your callback to produce the new DOM state.
  3. Captures a snapshot of the new state.
  4. Animates between old and new using a crossfade by default.
  5. Removes the old snapshot once the animation finishes.

The method returns a ViewTransition object with promises for each lifecycle phase — updateCallbackDone, ready, finished — and a skipTransition() method.

The CSS @view-transition at-rule opts both the old and new documents into view transitions on navigation:

@view-transition {
navigation: auto;
}

Per the spec (CSS View Transitions Module Level 2), cross-document transitions use the pageswap event on the old page and the pagereveal event on the new page to manipulate the transition.

Elements participate in named transitions via view-transition-name:

.hero {
view-transition-name: hero;
}

The browser generates pseudo-elements for the snapshot tree:

Pseudo-element Purpose
::view-transition Root overlay
::view-transition-group(<name>) Container for a named transition group
::view-transition-image-pair(<name>) Wraps old and new snapshots
::view-transition-old(<name>) The captured “old” snapshot
::view-transition-new(<name>) The captured “new” snapshot

You can animate these with standard CSS @keyframes:

::view-transition-old(hero) {
animation: fade-out 0.3s ease-out;
}
::view-transition-new(hero) {
animation: fade-in 0.3s ease-in;
}

view-transition-class (CSS View Transitions Level 2) groups multiple elements so they share the same transition styling without needing identical view-transition-name values.

The View Transitions API is specified across two W3C levels:

  • Level 1 (same-document / SPA): shipped in Chromium browsers (Chrome 111+). Safari and Firefox have added support in later versions.
  • Level 2 (cross-document / MPA): newer, with more recent browser support.

Per MDN, document.startViewTransition() is on the standards track and is no longer marked experimental.

If the API is unavailable, document.startViewTransition() is not defined. Feature-detect before calling:

if (!document.startViewTransition) {
// Just update the DOM directly
updateDOM();
return;
}
document.startViewTransition(() => updateDOM());

← Back to Performance.