View Transitions API Generator

Pick a transition type, drag the duration slider, fire a real document.startViewTransition() preview, then copy production-ready ::view-transition-* CSS.

About This Tool

The CSS View Transitions API is the first browser-native way to animate the gap between two snapshots of the DOM — without virtual DOM diffing libraries, FLIP helpers, or hand-rolled requestAnimationFrame choreography. You wrap a DOM mutation in document.startViewTransition(callback), and the browser captures a screenshot before, runs your callback, captures a screenshot after, and cross-fades between them inside special pseudo-elements (::view-transition-old(...) and ::view-transition-new(...)). This generator produces the exact CSS and JavaScript you need to ship that effect.

Pick a transition style — cross-fade, slide, scale, or custom keyframes — and the playground builds three things in real time: (1) the view-transition-name declaration that opts a specific element in, (2) the @keyframes blocks if you've chosen a non-default animation, and (3) the ::view-transition-old/::view-transition-new pseudo-element rules that bind your duration and easing to the snapshot. The duration slider runs from 200ms (snappy UI feedback) to 2000ms (cinematic), and the easing dropdown includes Material's standard curve, a spring overshoot, and a smooth ease-out you can drop straight into a design system.

The "Try Transition" button doesn't simulate anything — it actually calls document.startViewTransition() on the live demo card, so you see the exact result your visitors will see. A browser-support banner uses 'startViewTransition' in document to detect Chrome/Edge 111+, Safari 18+, and Firefox (currently behind a flag), and warns you when you're on a fallback path.

Pair this generator with the CSS Easing Editor to design custom cubic-bezier curves before pasting them into the easing dropdown, the Container Query Builder when your transitioning element responds to its parent's width, and the color-mix Generator to interpolate gradient stops between the "before" and "after" states. For the broader CSS playground experience, the text-wrap Playground follows the same browser-detection pattern.

All processing is client-side. No transition definitions, names, or generated code ever leave your browser — the playground works offline once loaded and is safe to use with unreleased product UI.

How to Use

  1. Pick a Transition type from the dropdown: cross-fade (the default the browser provides for free), slide, scale, or custom keyframes.
  2. Drag the Duration slider between 200ms and 2000ms. UI micro-interactions feel right around 200–400ms; modal opens around 300–500ms; full-page transitions 500–800ms.
  3. Choose an Easing functionease is the default, cubic-bezier(0.4, 0, 0.2, 1) matches Material Design, and cubic-bezier(0.34, 1.56, 0.64, 1) adds a playful overshoot.
  4. Edit the view-transition-name identifier. It must be unique per snapshot — non-alphanumeric characters are stripped automatically.
  5. Click Try Transition (or press Ctrl+Enter) to fire document.startViewTransition() on the demo card and see the exact CSS in action.
  6. Click Copy CSS (or press Ctrl+Shift+C) to copy the generated stylesheet, then Copy JS for a ready-to-paste startViewTransition wrapper.
  7. Paste the CSS into your global stylesheet and add the JavaScript helper around any DOM mutation — a class swap, route change, or React re-render — to make it animate.

Popular Examples

View all 15 examples →

FAQ

What is the View Transitions API?

The View Transitions API is a browser feature that animates between two states of the DOM without you writing any low-level animation code. You call document.startViewTransition(callback); the browser takes a screenshot of the page, runs your callback (which mutates the DOM), takes a second screenshot, and then cross-fades between them inside special ::view-transition-old() and ::view-transition-new() pseudo-elements. You can override the cross-fade with @keyframes to create slides, scales, or shared-element transitions. It shipped in Chrome 111 (March 2023), Safari 18 (September 2024), and is behind a flag in Firefox as of early 2026.

Which browsers support the View Transitions API?

Same-document transitions (the kind this generator produces) work in Chrome 111+, Edge 111+, Opera 97+, and Safari 18+. Firefox supports them behind the layout.css.view-transitions.enabled preference but does not enable it by default. Cross-document transitions (between MPA navigations) are newer — Chrome 126+ and Safari 18+. Always wrap your call in `if ('startViewTransition' in document)` so unsupported browsers fall back to an instant DOM swap; the generator's banner uses exactly that detection.

What is the difference between SPA and MPA View Transitions?

SPA (single-page application) transitions use document.startViewTransition(callback) — the JavaScript API. You call it inside React/Vue/Svelte route handlers or anywhere you mutate state. MPA (multi-page application) transitions are CSS-only: you add @view-transition { navigation: auto; } to both the source and destination pages, and the browser animates same-origin navigations automatically. SPA transitions are more flexible (you can transition any state change, not just navigation) but require JavaScript; MPA transitions are zero-JS but only fire on full navigations within the same origin.

Show me a minimal startViewTransition() example.

The simplest snippet is: `if (document.startViewTransition) { document.startViewTransition(() => { document.body.classList.toggle('dark'); }); } else { document.body.classList.toggle('dark'); }`. The else branch is the fallback for Firefox or older browsers — it just runs the mutation without animation. You can also chain the returned promises: `const t = document.startViewTransition(updateDom); await t.ready; // animations have begun; await t.finished; // they're done.` The ready promise is useful when you want to add JavaScript-driven Web Animations API tweaks on top of the snapshot pseudo-elements.

How do view-transition-name uniqueness rules work?

Each view-transition-name must be unique among visible elements in a single page snapshot. If two elements have the same name when document.startViewTransition() runs, the entire transition is skipped (and a warning is logged). This means you cannot apply view-transition-name: card to every card in a list — instead, generate a unique name per item like view-transition-name: card-${id}. For shared-element transitions across pages or routes, the same name on both the source and destination element tells the browser to morph between them; if either side is missing the name, the element falls back to the cross-fade group instead.

How do I gracefully fall back when View Transitions are unsupported?

Always feature-detect with `if (document.startViewTransition)` and run your DOM mutation in the else branch without animation. For MPA-style transitions, the @view-transition rule is silently ignored by browsers that do not understand it. For visual fallbacks (e.g., still wanting some animation in Firefox), you can layer a CSS transition on the element itself — when the View Transitions API kicks in, the snapshot replaces the live element so your CSS transition does not double-animate; when it does not, your CSS transition still runs. This 'progressive enhancement two-layer' pattern is the most resilient strategy.

Is my data safe?

Yes. This generator runs entirely in your browser using vanilla CSS, the View Transitions API, and React state — no transition names, durations, easing curves, or generated code are ever sent to a server. The browser-support banner uses the local `'startViewTransition' in document` check, not a remote feature-detection service. There is no analytics tied to your input, and the page works offline once loaded, so you can paste internal route names, design-system class names, or unreleased component identifiers without leaving any trace.

Related Tools