如何通過一行 CSS 代碼讓多頁面應用程序擁有單頁應用程序(SPA)的流暢體驗
多頁應用(MPA)勝在簡單;,每次整頁刷新帶來的白屏閃爍。 的套路是:先快照舊視圖,加載新頁,把二者平滑疊合——無需引入任何重量級框架,就能收獲。
一步就到位
@view-transition {
navigation: auto;
}把它放進每個頁面。自 Chrome 126+ / Edge 126+ / Safari 18.2+ 起,站內導航默認就有交叉淡化的轉場效果。
在 SPA 里怎么用
toggle.addEventListener('click', () =>
document.startViewTransition(() => article.classList.toggle('open'))
)回調跑完后,瀏覽器會把舊視圖截圖蓋上,然后平滑淡出。把昂貴的 DOM 變更集中在這個回調里,就能把重排成本壓到一次。
給單個元素“對齊”動畫(view-transition-name)
img {
view-transition-name: hero;
}只要兩頁上為同一個視覺元素使用同名,瀏覽器就會自動插值它的位置/尺寸/透明度,像是把同一個對象“搬運”到了新頁面。
用偽元素寫出品牌動效
::view-transition-old { animation: fade-out .3s ease-out; }
::view-transition-new { animation: fade-in .3s ease-out; }
@keyframes fade-in { from {opacity:0} to {opacity:1} }
@keyframes fade-out { from {opacity:1} to {opacity:0} }默認是交叉淡化;不過你可以用上面的偽元素來自定義節奏與曲線,讓過渡更符合品牌語氣。
漸進增強 / 無障礙
if (matchMedia('(prefers-reduced-motion: reduce)').matches)
document.startViewTransition?.(() => {})?.skipTransition()再配合 CSS.supports('view-transition-name: x') 做特性檢測——支持則加分,不支持就走普通加載,優雅退化。
RandomDoggo 演示 ??:
圖片
性能小抄
- 資源要輕:越輕越流暢。
- 改動打包:把 DOM 重活塞進 startViewTransition 回調,減少多次布局/繪制。
- 慎用大濾鏡/陰影:::view-transition-* 上的大 filter / box-shadow 會吃滿 GPU 填充率。
兼容性(2025/06)
? Chrome 126 / Edge 126 / Safari 18.2 / Opera 112 ? Firefox
最佳實踐
- 僅“安全導航”觸發:同源、且不觸發整頁刷新(如 location.reload),也不被 iframe/sandbox 攔截。
- beforeunload 會“叫?!保喝我?nbsp;beforeunload 監聽都將取消轉場。
- DevTools 查阻斷:Chrome DevTools → More Tools → Animations 能標注被誰阻斷。
- 尊重“減少動畫”:
@media not (prefers-reduced-motion: reduce) {
@view-transition {
navigation: auto;
}
}于是只有在用戶歡迎動畫時,那“一行”才會啟用。
之后會更香
- Navigation API × View Transitions:無閃爍的歷史操作指日可待。
- **match-element**(view-transition-name 未來值):不需要相同 ID,也能把兩頁元素配對起來做動畫。




















