CSS View Transitions API: Multi-Page Animations
The CSS View Transitions API enables native, seamless animated transitions between different HTML documents in multi-page applications (MPAs) without requiring complex client-side JavaScript routing. This article explains how the API bridges navigation states, how browsers capture and animate page snapshots, and how developers can implement and customize cross-document transitions using modern CSS properties.
The Mechanism of Cross-Document Transitions
Traditionally, navigating between separate HTML pages resulted in a visible flash of white or an abrupt content replacement as the browser unloaded the current document and parsed the next. The View Transitions API solves this by capturing visual representations of both states and smoothly morphing between them.
During a cross-document navigation, the browser coordinates the transition through several distinct steps:
- Triggering Navigation: When a user clicks a link to a same-origin URL, the browser checks if both the current page and the destination page support view transitions.
- Snapshotting the Old State: Before discarding the current page, the browser takes a visual snapshot of the DOM elements participating in the transition.
- Fetching and Rendering the New State: The browser fetches the destination page and builds its DOM. Before painting it to the screen, the browser freezes the rendering pipeline and takes a snapshot of the new state.
- Generating Pseudo-Elements: The browser creates a temporary tree of pseudo-elements on the new document containing the old and new snapshots.
- Running the Animation: A default cross-fade animation runs using CSS keyframes, seamlessly transitioning from the old snapshot to the live new document.
Enabling Multi-Page Transitions
To activate cross-document view transitions, both the outgoing and
incoming documents must explicitly opt in. This is achieved using the
@view-transition at-rule in your stylesheet:
@view-transition {
navigation: auto;
}Both pages must belong to the same origin (protocol, domain, and port). If either page omits this rule or if the navigation is cross-origin, the browser falls back to standard page load behavior.
The Pseudo-Element Tree
Once activated, the browser constructs an ephemeral pseudo-element tree rooted at the document root:
::view-transition: The root container that overlays the entire viewport.::view-transition-group(root): Controls the size and position of a specific transition group.::view-transition-image-pair(root): Houses both the outgoing and incoming visual states.::view-transition-old(root): A static snapshot of the previous page.::view-transition-new(root): A live representation of the incoming page.
By default, the browser interpolates the opacity of the
old and new snapshots to create a smooth cross-fade, while adjusting
dimensions and position if elements change size or location.
Animating
Specific Elements with view-transition-name
While the default transition applies to the entire page
(root), you can animate individual persistent elements—such
as headers, hero images, or cards—by assigning them a unique
view-transition-name:
.product-card-image {
view-transition-name: product-image;
}If an element on the destination page shares the same
view-transition-name, the browser isolates those elements
into their own dedicated
::view-transition-group(product-image) branch. The browser
then automatically animates the element’s geometry, position, and visual
properties across pages, creating an app-like shared element
transition.
Customizing the Animation
Because view transitions are driven by standard CSS animations, you can override default timing functions, durations, or keyframes by targeting the transition pseudo-elements:
::view-transition-old(root) {
animation: 300ms ease-out both slide-out-left;
}
::view-transition-new(root) {
animation: 300ms ease-in both slide-in-right;
}
@keyframes slide-out-left {
to { transform: translateX(-100%); }
}
@keyframes slide-in-right {
from { transform: translateX(100%); }
}By leveraging hardware-accelerated snapshot interpolation through pure CSS, the View Transitions API removes the need to convert multi-page architectures into single-page applications solely for polished navigation experiences.