Drop Your Animation Library: 5 Lines to Make Your SPA Feel Like a Native App
Source: Dev.to
How it works
The browser performs three steps under the hood:
- Takes a screenshot of the old state.
- Runs your callback to update the DOM.
- 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.
Comparison with popular animation libraries
| Feature | View Transitions API | Framer Motion | GSAP |
|---|---|---|---|
| Bundle size | 0 KB | ~50 KB | ~25 KB |
| React dependency | None | Required | None |
| 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
- Elements animate as images during the transition;
font-sizechanges orclip-pathwon’t apply in the animation phase. view-transition-namemust be unique per page, e.g.view-transition-name: item-${id};.- Firefox MPA support is pending.
document.startViewTransitionworks in Firefox 133+. The@view-transition { navigation: auto }rule is expected sometime in 2026—use@supportsas 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.