Smooth Page-To-Page Animations With Almost No Code
View Transitions
The View Transitions API animates between DOM states. Frameworks hook into it; you can also use it on regular static sites.
What you'll learn
- Enable cross-document view transitions
- Use `view-transition-name` for shared elements
- Style the transitions with CSS
The View Transitions API animates DOM state changes. The CSS bits do most of the work; a one-line opt-in plus per-element animations.
Multi-Page View Transitions (No Framework Needed)
Add this to every page that should participate:
@view-transition {
navigation: auto;
} Now in supporting browsers, clicking a link between same-origin pages cross-fades by default — no JS, no framework.
Same-Element Across Pages
To “morph” one element into its counterpart on the next page,
give both elements the same view-transition-name:
/* On both pages */
.article-hero {
view-transition-name: hero;
} The browser captures the element on the outgoing page, then
animates it to the matching view-transition-name on the incoming
page. Position, size, even shape — interpolated.
Names must be unique on a page. Common pattern: view-transition-name: var(--name)
where each item provides its own name.
Style The Transitions
The browser exposes pseudo-elements:
::view-transition-old(root) {
animation: fade-out 200ms;
}
::view-transition-new(root) {
animation: fade-in 200ms;
}
@keyframes fade-out { to { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } } Replace root with a specific view-transition-name to control
that element’s transition individually.
Same-Page (Single-Document) Transitions
For state changes within a single page (filter the list, toggle a view), trigger from JS:
document.startViewTransition(() => {
applyTheNewState();
}); The browser captures the DOM, runs the callback, captures the new DOM, animates between them.
Browser Support
Chromium-based browsers — yes. Firefox / Safari — in progress. Sites that use the multi-page variant degrade gracefully (instant navigation) on browsers without support.
Up Next
Deploying a static HTML/CSS site.
Deployment →