interactionadvanced

View Transition

The browser-native View Transitions API that animates between DOM states or page navigations using a screenshot-based crossfade, with no JavaScript animation library needed.

Plain English

Before the View Transitions API, creating a smooth animated transition between two pages or two UI states required either a JavaScript animation library or complex manual DOM manipulation — clone the old state, animate both, swap, clean up. The View Transitions API delegates all of that to the browser in two lines: document.startViewTransition(() => updateTheDom()). The browser takes a snapshot of the current state, applies the DOM update, then crossfades between the old and new snapshots — by default with a 300ms opacity crossfade. The real power comes from named elements: assign view-transition-name: card-hero to an element in both states and the browser will automatically animate that element from its old position and size to its new one, producing the "shared element transition" effect (the card flying from the list into the detail page) that previously required significant engineering effort.

Technical

Same-document: document.startViewTransition(async () => { await updateDOM(); }). Multi-page (MPA): add @view-transition { navigation: auto; } in CSS (Chrome 126+). Named elements: view-transition-name: hero-image on matching elements in old/new state — browser auto-animates position/size. Custom animation: ::view-transition-old(root) and ::view-transition-new(root) are pseudo-elements you can target with @keyframes. SPA frameworks: Next.js supports MPAs via the App Router's soft navigation + unstable_ViewTransition (experimental); React Router 7 has built-in support. Browser support: Chrome 111+ (same-doc), Chrome 126+ (MPA). Firefox and Safari: in development as of mid-2025 — always guard with if (!document.startViewTransition) { fallback(); }.

Live Demo

View Transition API

Simulates the View Transitions API — the shared card element morphs between its position in the list and the hero position on the detail page.

/playbook/

All Terms

D
Design SystemsClick →
T
Typography Scale
C
Color Theory
S
Spacing Rhythm
view-transition-name: "shared-card"

The View Transitions API animates shared elements between page states — no JS animation library needed.

Usage

✓ Good usage

A card grid where clicking a card triggers a view transition — the card's image expands in place to fill the detail page header using view-transition-name on the image, producing a native-app-quality shared element animation with 4 lines of code.

✗ Bad usage

Wrapping every small DOM mutation (toggling a class, updating a counter) in startViewTransition() — the API adds a compositing frame for every call, and overuse on frequent updates causes dropped frames rather than smoothness.

Common mistakes

AI Prompt Example

Copy this into Claude, Cursor, Bolt, or v0.

Add view transitions to the product listing → detail navigation. In the listing, give each product card image view-transition-name: product-image-{id}. In the detail page, give the hero image the same view-transition-name. Wrap the router push in document.startViewTransition(() => router.push(url)) with a feature check: if (!document.startViewTransition) { router.push(url); return; }. Add a custom slide-and-fade: ::view-transition-old(root) animates out left, ::view-transition-new(root) slides in from right, both at 280ms cubic-bezier(0.4, 0, 0.2, 1).