Creating Seamless Page Transitions with the View Transitions API
1. The Experience Gap in Page Navigation
In web development, we have long faced a dilemma in user experience:
- Multi-Page Applications (MPAs): Their architecture is simple and stable, but every navigation performs a complete page load, causing a “white screen” or “flash” and breaking continuity.
- Single-Page Applications (SPAs): Frontend routing provides a smooth experience without page reloads, but developers must manually handle complex transition animations, state management, and code splitting, which makes development expensive.
Is there a way to retain the simplicity of an MPA while gaining the smooth transitions of an SPA? The View Transitions API was created for exactly this purpose.
2. What Is the View Transitions API?
The View Transitions API is a native browser API that provides a mechanism for easily creating animated transitions between two different DOM states.
Its core workflow is very simple:
- When you trigger a transition, the API takes a “snapshot” of the current page (the old state).
- You then use JavaScript to update the DOM to its new state.
- The API also takes a “snapshot” of the new page (the new state).
- Finally, the browser creates a smooth default transition, usually a cross-fade, between the “old snapshot” and the “new snapshot.”
The browser handles all of this efficiently at a low level; we only need to call a simple function.
3. How Do You Use It?
Using View Transitions in a single-page application is very simple. Just wrap your DOM update logic in the document.startViewTransition function.
// 假设你有一个更新页面内容的函数
async function updatePageContent(url) {
const response = await fetch(url);
const newHtml = await response.text();
// 用新内容替换旧内容 (具体实现取决于你的架构)
document.body.innerHTML = newHtml;
}
// 在导航链接的点击事件中调用
document.querySelector('a').addEventListener('click', (event) => {
event.preventDefault();
const url = event.target.href;
// 检查浏览器是否支持
if (!document.startViewTransition) {
updatePageContent(url); // 不支持则直接更新
return;
}
// 使用 View Transition
document.startViewTransition(() => updatePageContent(url));
});That alone gives your page navigation a default cross-fade effect!
4. Customizing the Transition Animation
The default cross-fade is excellent, but the API’s real power lies in its customizability. When startViewTransition runs, the browser creates a DOM structure containing these pseudo-elements:
::view-transition: The root element that contains the entire transition.::view-transition-old(root): The “snapshot” of the old view.::view-transition-new(root): The “snapshot” of the new view.
We can override the default effect with a CSS animation, for example to create a slide-in animation:
@keyframes slide-in {
from { transform: translateX(100%); }
}
::view-transition-new(root) {
animation: slide-in 0.5s ease-out;
}5. “Morphing” Between Elements: view-transition-name
The API’s most impressive capability is recognizing different elements on two pages as the same object and creating a smooth “morphing” animation between them.
This is implemented through the view-transition-name CSS property.
Page A (list page):
<img src="thumbnail.jpg" style="view-transition-name: hero-image;" />Page B (detail page):
<img src="full-size.jpg" style="view-transition-name: hero-image;" />When navigating from Page A to Page B, the browser sees that both elements have the same view-transition-name. It automatically calculates the differences in their position, size, and shape, then generates a smooth transition instead of a simple cross-fade. This works especially well for transitions involving images, cards, and similar elements.
Conclusion
The View Transitions API brings long-awaited native transition capabilities to the web. It greatly simplifies interactions that previously required complex JavaScript animation libraries, making cinematic and fluid application experiences easier to create than ever. As frameworks such as Astro and Nuxt integrate it, and as support for multi-page applications becomes more widespread, it is certain to become a standard skill for modern web developers.