DEV Community

linou518
linou518

Posted on

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

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

Are you importing Framer Motion just for page transitions?
Writing opacity + transform by hand every time you switch views in your SPA?

In October 2025, the View Transitions API landed in Baseline — zero dependencies, five lines of code, supported in all major browsers except Firefox (for MPA mode).


What It Actually Does

In short: it automatically animates between before and after DOM states.

The browser does three things 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. Users just see a smooth transition. Default is crossfade. Add CSS and you can do slides, morphs — anything.


Dropping It Into a Real SPA: 5 Lines

I tested this on a Flask + SPA internal dashboard I maintain. Here's the original view-switching code:

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

Making it View Transitions-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 {
    doSwitch(); // fallback: works normally without animation
  }
}
Enter fullscreen mode Exit fullscreen mode

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


Customizing the Animation

If the default fade isn't your thing, override it 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; }
}
Enter fullscreen mode Exit fullscreen mode

Element-Level Morphing

The real power move is 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; }
Enter fullscreen mode Exit fullscreen mode

Click to expand, click to collapse — native app feel without GSAP.


vs. Framer Motion / GSAP

View Transitions API Framer Motion GSAP
Bundle Size 0 KB ~50 KB ~25 KB
React dependency None Required None
MPA support
Firefox ❌ (MPA) / ✅ (SPA)

For MPAs (multi-page apps), it's even simpler — just two lines of CSS for full page-transition animation:

@view-transition {
  navigation: auto;
}
Enter fullscreen mode Exit fullscreen mode

Gotchas to Avoid

1. Elements animate as images during the transition
The snapshot is a bitmap — so font-size changes or clip-path won't apply during the animation phase.

2. view-transition-name must be unique per page
If multiple elements share the same name, only the last one gets transitioned. For dynamic lists, use view-transition-name: item-${id}.

3. Firefox MPA support is pending
SPA (startViewTransition) works in Firefox 133+. MPA (@view-transition { navigation: auto }) is expected sometime in 2026 — use @supports as a fallback for now.


TL;DR

  • SPA: Wrap your existing DOM updates in document.startViewTransition()
  • MPA: 2 lines of CSS for instant page-transition animation
  • Graceful degradation: Unsupported browsers just update the DOM normally — nothing breaks
  • Cost: 0 KB

Before reaching for a new library, check what the browser already ships for free. That discipline, applied consistently, is what keeps codebases maintainable long-term.

Top comments (0)