Home / Snippets / Animation /

Navigation transition

Animate between navigation states with a slide and fade — simulating View Transitions in a pure-CSS demo.

New feature
animationui

Quick implementation

/* Enable cross-document View Transitions */
@view-transition {
  navigation: auto;
}

/* Default: cross-fade (built-in) */

/* Custom: slide-fade for page content */
::view-transition-old(root) {
  animation: nav-out 0.35s ease both;
}

::view-transition-new(root) {
  animation: nav-in 0.35s ease both;
}

@keyframes nav-out {
  to {
    opacity: 0;
    transform: translateX(-2rem);
  }
}

@keyframes nav-in {
  from {
    opacity: 0;
    transform: translateX(2rem);
  }
}

/* Keep header stable during transition */
.page-header {
  view-transition-name: header;
}

::view-transition-group(header) {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.01s;
  }
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer adding page navigation transitions.

Goal: Smooth slide-fade animation between page navigations using the View Transitions API.

Technical constraints:
- Enable with @view-transition { navigation: auto } for MPA sites.
- Override ::view-transition-old(root) and ::view-transition-new(root) with custom @keyframes.
- Keep persistent elements (header, nav) stable by assigning them view-transition-name and animation: none.
- Use oklch() for all color values — no hex or rgba().
- Duration 0.3–0.4s with ease timing.

Framework variant (pick one):
A) MPA — CSS-only, works with standard <a> links between pages.
B) React SPA — wrap router transitions in document.startViewTransition(), CSS handles animation.

Edge cases to handle:
- Respect prefers-reduced-motion: reduce animation duration to near-instant.
- Back navigation should reverse the slide direction (configurable via navigation API types).
- Browsers without View Transitions support simply skip the animation — no broken layout.

Return CSS.

Why this matters in 2026

Before the View Transitions API, animated page navigations required SPAs with client-side routers and libraries like Barba.js. Now, a single CSS rule — @view-transition { navigation: auto } — enables cross-document transitions on plain multi-page sites. This levels the playing field: a static site with regular <a> links can have app-like navigation animations, and the browser handles the snapshot, overlay, and cleanup.

The logic

When navigation occurs, the browser snapshots the old page as ::view-transition-old(root) and renders the new page as ::view-transition-new(root). Custom @keyframes on these pseudo-elements control the exit and entry animations. Persistent elements like the header can opt out of the page-level transition by receiving their own view-transition-name — the browser then morphs them in place instead of cross-fading with the page. For SPAs, wrap state changes in document.startViewTransition() to trigger the same mechanism.

Accessibility & performance

View Transitions are compositor-composited — the old and new pages are rendered as GPU textures and animated as images, so no layout work happens during the transition. Always wrap custom animations in prefers-reduced-motion. The API has no impact on document loading — the new page still loads and becomes interactive at the normal time; the animation is purely visual. Screen readers and keyboard navigation are unaffected.