CSS View Transitions API

Native, framework-free animated transitions between two DOM states or two same-origin documents. The browser snapshots the old and new views, then cross-fades or morphs named elements between them. Replaces the JS-heavy FLIP and route-animation libraries for most cases.

Design Position

Field Value
Design family CSS and platform primitives
Use when Use when browser-native UI behavior depends on CSS View Transitions API.
System map Design System Map
Proof path Browser support, progressive enhancement, responsive behavior, and reduced-motion/accessibility checks where relevant.

Two flavors

Same-document (SPA): document.startViewTransition(() => updateTheDOM()). The callback mutates the DOM, the browser animates old to new. Shipped in Chrome 111 (2023). Wrap in a capability check (if (!document.startViewTransition)) so unsupported browsers update instantly with no animation. Source: W3C CSS View Transitions Level 1, https://drafts.csswg.org/css-view-transitions/, 2026-05-31

Cross-document (MPA): opt in by adding @view-transition { navigation: auto; } to both the outgoing and incoming same-origin pages. No JavaScript and no meta tag required. Browsers without support fall back to a normal navigation, so it is pure progressive enhancement. Source: web.dev / trade-assistance 2026 guide, https://trade-assistance.com/blog/cross-document-view-transitions-mpa-2026/, 2026-05-31

How the animation is built

By default a transition is a full-page crossfade. To morph a specific element, give it view-transition-name: hero (the name must be unique per page). The browser then animates that element's position, size, and content independently of the page fade.

Customize each part with the generated pseudo-elements: ::view-transition-old(name), ::view-transition-new(name), and the wrapping ::view-transition-group(name). Target them with normal @keyframes and CSS animations. Source: MDN View Transitions API, https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API, 2026-05-31

Cross-document lifecycle hooks

For MPA transitions, set names and transition types just-in-time with two events:

  • pageswap fires on the old page before it unloads. Read event.viewTransition, optionally skipTransition() for back/forward (traverse) navigations.
  • pagereveal fires on the new page before first paint. Add types with event.viewTransition.types.add('coming-from-list') to switch keyframes per route. Source: W3C CSS View Transitions Level 2, https://drafts.csswg.org/css-view-transitions-2/, 2026-05-31

Pair with the Speculation Rules API (prefetch / prerender) so the next document is ready before the user clicks, which makes the transition feel as instant as a native app.

Browser support (2026-05-31)

Feature Chrome / Edge Safari Firefox
Same-document 111+ 18.0+ partial
Cross-document 126+ 18.2+ flag / Nightly partial

Cross-document support sits near 85% of tracked usage. Firefox exposes both behind flags only, so treat MPA transitions as enhancement, never a hard dependency. Source: caniuse cross-document view transitions, https://caniuse.com/cross-document-view-transitions, 2026-05-31

Design-engineering guidance

  • Use it for thumbnail to hero morphs (list to detail), tab and filter changes, and full marketing or docs page navigations where it is free polish.
  • Keep one or two named morphs per transition. Naming everything produces noise and breaks the snapshot when names collide.
  • Always gate decorative motion with @media (prefers-reduced-motion: reduce); skip or shorten the transition. See Motion 3D Playbook for timing defaults.
  • In React, the experimental <ViewTransition> component and startTransition integrate with this API; see Frontier Stack 2026 for stack placement. For Sigil and Dedalus surfaces, prefer the native API over a route-animation library.
  • Plumbing (@view-transition, global keyframes) belongs in globals.css per CSS UI Enforcement; components stay cn()-first.

Timeline

  • 2026-07-01 | Design category refresh added this page to the CSS and platform primitives family, linked it to Design System Map, and kept it standalone because CSS View Transitions API owns a distinct design decision surface in this family. Source: User request, 2026-07-01
  • 2026-05-31 | Page created. Captured the same-document vs cross-document split, the @view-transition opt-in, view-transition-name morphing, the ::view-transition-* pseudo-elements, pageswap / pagereveal hooks, Speculation Rules pairing, and the Chrome 126+ / Safari 18.2+ / Firefox-flag support matrix. Source: caniuse + W3C View Transitions L1/L2 + MDN + web.dev, 2026-05-31