Drop Your Animation Library: 5 Lines to Make Your SPA Feel Like a Native App

Published: (March 1, 2026 at 07:06 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

How it works

The browser performs three steps under the hood:

  1. Takes a screenshot of the old state.
  2. Runs your callback to update the DOM.
  3. Takes a screenshot of the new state and animates the diff.

Everything happens within a single frame, so users see a smooth transition. The default animation is a cross‑fade; with CSS you can create slides, morphs, or any effect you like.

Example: Original view‑switching code

// original SPA view switch
function showView(name) {
  document.querySelectorAll('.view').forEach(v => v.style.display = 'none');
  document.getElementById('view-' + name).style.display = 'block';
  updateActiveNav(name);
}

Making it View‑Transition‑aware

function showView(name) {
  const doSwitch = () => {
    document.querySelectorAll('.view').forEach(v => v.style.display = 'none');
    document.getElementById('view-' + name).style.display = 'block';
    updateActiveNav(name);
  };

  if (document.startViewTransition) {
    document.startViewTransition(doSwitch);
  } else {
    // fallback: works normally without animation
    doSwitch();
  }
}

That’s it. The overview → family → nodes tab switches now have a soft cross‑fade. No build step, no new dependency, no bundle‑size increase.

Customising the transition with CSS

/* Slide left‑to‑right */
::view-transition-old(root) {
  animation: slide-out 0.25s ease-out;
}
::view-transition-new(root) {
  animation: slide-in 0.25s ease-out;
}

@keyframes slide-out {
  to { transform: translateX(-40px); opacity: 0; }
}
@keyframes slide-in {
  from { transform: translateX(40px); opacity: 0; }
}

Using view-transition-name

Give the same name to elements across two states and the browser automatically interpolates their position and size.

/* Same name on thumbnail and fullscreen view */
.thumbnail   { view-transition-name: hero-image; }
.fullscreen  { view-transition-name: hero-image; }

Now clicking to expand or collapse feels native—without pulling in GSAP or Framer Motion.

FeatureView Transitions APIFramer MotionGSAP
Bundle size0 KB~50 KB~25 KB
React dependencyNoneRequiredNone
MPA support
Firefox support❌ (MPA) / ✅ (SPA)

View Transitions for MPAs (Multi‑Page Apps)

For full‑page transitions you only need two lines of CSS:

@view-transition {
  navigation: auto;
}

Key notes

  1. Elements animate as images during the transition; font-size changes or clip-path won’t apply in the animation phase.
  2. view-transition-name must be unique per page, e.g. view-transition-name: item-${id};.
  3. Firefox MPA support is pending. document.startViewTransition works in Firefox 133+. The @view-transition { navigation: auto } rule is expected sometime in 2026—use @supports as a fallback for now.

Graceful degradation – unsupported browsers simply update the DOM normally, so nothing breaks.

Takeaway

Before reaching for a new animation library, check what the browser already ships for free. The View Transitions API provides a lightweight, dependency‑free way to give your SPA (or MPA) a native‑app feel with virtually no code.

0 views
Back to Blog

Related posts

Read more »