Featured image of post Smooth Page Transitions with View Transitions API Featured image of post Smooth Page Transitions with View Transitions API

Smooth Page Transitions with View Transitions API

Learn how to build seamless page navigations and hero image animations with minimal CSS and JavaScript using the native View Transitions API.

Introduction

Providing dynamic page transitions is a key factor in elevating the overall user experience (UX) of modern web applications.

Historically, to morph or fade elements smoothly between page navigations, developers had to import heavy JavaScript libraries like Framer Motion or GSAP. These libraries require deep hooks into rendering lifecycles to delay unmounting while animating old DOM nodes.

The introduction of the W3C standard View Transitions API simplifies this. It allows browsers to natively capture states and interpolate page layout updates with minimal CSS and JavaScript.


1. What is the View Transitions API?

The View Transitions API works by capturing snapshot states of the page before and after a DOM modification, automatically running a hardware-accelerated crossfade or morph animation between the two states.

Core Benefits

  • Reduced Boilerplate: No need to handle timers, keyframes, or state hooks in JS to defer page rendering.
  • Excellent Performance: Because transitions run natively on the GPU thread, visual frame drops are minimized.
  • SPA & MPA Compatibility: Initially built for Single Page Applications, browser support has expanded to cover Multi-Page Applications (MPAs).

2. Basic Setup (SPA Example)

Let’s look at how to apply transitions during a DOM update in a standard application.

Traditional DOM Update

// The content updates instantly with no transition
function updateContent() {
  document.querySelector('.content').innerHTML = '<h1>New Heading</h1>';
}

Implementing View Transitions

Simply wrap your DOM updating function inside the browser’s document.startViewTransition() callback.

function updateContent() {
  // Check browser capability
  if (!document.startViewTransition) {
    document.querySelector('.content').innerHTML = '<h1>New Heading</h1>';
    return;
  }

  // Animate the update
  document.startViewTransition(() => {
    document.querySelector('.content').innerHTML = '<h1>New Heading</h1>';
  });
}

With just this wrapper, the browser captures the outgoing and incoming states, executing a 0.25-second crossfade by default.


3. Customizing Transitions via CSS

To customize the default crossfade animation, you can target specific pseudo-elements exposed by the layout engine during transition states.

When startViewTransition is called, the browser constructs a temporary pseudo-element tree:

::view-transition
 └─ ::view-transition-group(root)
     └─ ::view-transition-image-pair(root)
         ├─ ::view-transition-old(root)  (Outgoing page snapshot)
         └─ ::view-transition-new(root)  (Incoming page snapshot)

To create a slide-out and slide-in transition instead of a crossfade, add the following to your stylesheet:

/* Disable default crossfades and bind custom keyframes */
::view-transition-old(root) {
  animation: 0.3s ease-out both slide-out;
}

::view-transition-new(root) {
  animation: 0.3s ease-out both slide-in;
}

@keyframes slide-out {
  to { transform: translateX(-100%); }
}

@keyframes slide-in {
  from { transform: translateX(100%); }
}

4. Part-level Morph Animations (Hero Transitions)

A standout feature of the View Transitions API is its ability to automatically morph individual layout elements across pages—such as an image expanding from a card list into a detail page header.

Setting Up CSS Name Bindings

To link elements together, apply the same view-transition-name property to both the outgoing and incoming elements:

/* Card list image on the listing page */
.card-thumbnail {
  view-transition-name: article-hero-image;
}

/* Featured header image on the detail page */
.detail-main-image {
  view-transition-name: article-hero-image;
}

The browser matches the transition name during page rendering, automatically calculating size and coordinate offsets to animate the element smoothly into its new position.


Conclusion & Browser Support

The View Transitions API is supported in Chromium-based browsers (Chrome, Edge) and Safari, with implementations underway for Firefox.

Using this API, you can add high-performance page transitions to your web app using CSS. Try wrapping your main routing changes in startViewTransition to experience it firsthand.