Journal Development
The View Transitions API: App-Like Feel Without an SPA
App-like page transitions no longer require turning your site into an SPA. How do you build fluid transitions on a classic multi-page site with the View Transitions API?
- Published
- Reading time
- 5 minutes
- By
- Webify
For years there was only one way to get app-like page transitions: turn the site into an SPA, hand routing over to JavaScript and pay for it in bundle size. The View Transitions API changed that equation. Smooth, meaningful transitions between pages are now possible even on a classic multi-page (MPA) site, with a single line of CSS.
Cross-Page Transitions in One Line
To enable a transition between two same-origin pages, add this rule to the CSS of both pages:
@view-transition {
navigation: auto;
} The browser takes a snapshot of the old page, loads the new one and applies a cross-fade between them by default. In supporting browsers (Chrome and Edge 126+, Safari 18.2+) this just works. In others nothing breaks; the page opens as usual. It is a textbook case of progressive enhancement.
Linking Elements Across Pages
The really striking part is linking the "same" element on two pages. A title in the blog list, for example, can grow into the large headline on the article page when clicked. To do that, give both elements the same view-transition-name:
/* List page */
.post-card h2 { view-transition-name: post-title; }
/* Article page */
.article h1 { view-transition-name: post-title; }
/* Customise the duration and easing */
::view-transition-group(post-title) {
animation-duration: 0.45s;
animation-timing-function: cubic-bezier(0.2, 0, 0, 1);
}
The one rule to keep in mind: a view-transition-name must be unique on the page. If a list has several cards, the names need to be generated dynamically (such as post-title-1, post-title-2).
"A good transition tells users where they came from and where they are going. It is a wayfinding tool, not decoration."
Performance and Accessibility
View Transition animations run on the browser's own compositing layer, so they do not burden the main thread. A few principles still matter:
- Keep transitions short; 300–500ms is enough in most cases.
- Turn them off for motion-sensitive users: use
navigation: noneinside@media (prefers-reduced-motion: reduce). - If the next page loads slowly, the transition keeps users waiting, so View Transitions work best paired with a fast server response and prerendering.
@media (prefers-reduced-motion: reduce) {
@view-transition { navigation: none; }
} Conclusion
A mostly static, fast-loading site and fluid, app-like transitions are no longer alternatives to each other. When static-first architectures like Astro meet the browser's built-in View Transitions support, the same premium experience is possible without the JavaScript weight of an SPA.