View Transitions API 頁面過場動畫原生實作完整教學:告別 JavaScript 動畫庫
View Transitions API 是什麼
還記得以前為了實作頁面切換動畫,需要引入整個 Framer Motion 或 GSAP 嗎?那些日子可能要結束了。View Transitions API 是瀏覽器原生提供的頁面過場動畫 API,讓你用幾行 CSS 就能實現以前需要大量 JavaScript 才能做到的效果。
我第一次在專案中使用 View Transitions API 時,真的有種「這就對了」的感覺。以前要做一個列表頁到詳情頁的平滑過場,光是處理動畫邏輯、DOM 快照、時序控制就要寫上百行程式碼。現在,瀏覽器幫你處理了大部分工作。
View Transitions API 的核心原理是:在 DOM 更新前後,瀏覽器分別擷取頁面的快照(snapshot),然後在兩個快照之間執行你定義的 CSS 動畫。這個過程完全在渲染引擎層面處理,所以效能比 JavaScript 驅動的動畫好很多。
它支援兩種模式:Same-Document Transitions(SPA 模式)和 Cross-Document Transitions(MPA 模式)。前者用在 SPA 框架中的路由切換,後者用在傳統的多頁面網站。
瀏覽器支援
截至 2026 年初,View Transitions API 的支援狀況已經相當不錯了:
Same-Document Transitions(SPA 模式):Chrome 111+、Edge 111+、Opera 97+、Safari 18+。Firefox 從 126 版開始支援。基本上主流瀏覽器都已經支援。
Cross-Document Transitions(MPA 模式):Chrome 126+、Edge 126+。Safari 和 Firefox 的支援還在進行中。
對於不支援的瀏覽器,View Transitions API 會優雅降級——DOM 更新照常進行,只是沒有動畫效果。這代表你可以放心使用它,不用擔心在舊瀏覽器上出錯。
我的建議是:SPA 模式現在就可以放心在正式產品中使用;MPA 模式可以開始在新專案中嘗試,但要做好降級處理。
SPA 基本用法
在 SPA 中使用 View Transitions API 非常直覺。核心 API 只有一個方法:document.startViewTransition()。
最基本的用法是把你的 DOM 更新操作包在 startViewTransition 的 callback 中。例如:當使用者點擊一個項目時,你在 callback 中更新頁面內容,瀏覽器就會自動在新舊內容之間產生過場動畫。
預設的過場效果是交叉淡入淡出(cross-fade),舊內容淡出的同時新內容淡入。光是這個預設效果就已經比沒有任何過場好很多了。
startViewTransition 回傳一個 ViewTransition 物件,你可以用它來追蹤過場的生命週期。它有幾個 Promise 屬性:ready(動畫準備就緒)、updateCallbackDone(DOM 更新完成)、finished(動畫播放完畢)。這些 Promise 讓你可以在適當的時機執行額外的邏輯。
如果你之前學過 CSS Scroll-Driven Animations,會發現 View Transitions API 的設計哲學一脈相承——把以前需要 JavaScript 的動畫能力,逐步移到 CSS 和瀏覽器原生層面。
CSS 自定義過場動畫
預設的 cross-fade 太單調了?別擔心,View Transitions API 的真正強大之處在於你可以用 CSS 完全自定義過場動畫。
過場動畫涉及兩個偽元素:::view-transition-old(root) 代表舊內容的快照,::view-transition-new(root) 代表新內容的快照。你可以對這兩個偽元素套用任何 CSS animation。
舉幾個常見的過場效果:
滑入效果:讓舊內容往左滑出、新內容從右滑入。這只需要定義兩個 @keyframes,分別控制 old 和 new 的 transform: translateX 值。
縮放效果:從中心點放大展開或縮小收起。用 transform: scale 配合 opacity 就能實現。
圓形遮罩效果:用 clip-path: circle() 來實現從一個圓形展開覆蓋整個頁面的效果。這個效果在 Material Design 中很常見,以前實作起來很麻煩,現在用 CSS 就能搞定。
你甚至可以根據導航方向來套用不同的動畫。例如,往前導航時新頁面從右邊滑入,往後導航時從左邊滑入。這需要在 JavaScript 中判斷導航方向,然後在 document.documentElement 上設定一個 data attribute,CSS 再根據這個 attribute 來選擇動畫。
元素級動畫
整頁過場只是基礎。View Transitions API 最令人興奮的功能是元素級動畫——讓特定元素在頁面切換時產生獨立的過場效果。
做法是在 CSS 中對特定元素設定 view-transition-name 屬性。例如,在列表頁中給產品圖片設定 view-transition-name: product-image,在詳情頁的大圖也設定相同的名稱。當頁面切換時,瀏覽器會自動偵測到兩個頁面中有相同 view-transition-name 的元素,並在它們之間產生平滑的過渡動畫——位置、大小、形狀都會自動補間。
這就是所謂的「Shared Element Transition」(共享元素過場),以前在 Android 原生開發中很常見,但在 Web 上一直很難實作。現在只要一個 CSS 屬性就搞定了。
需要注意的是:view-transition-name 的值在同一個頁面中必須是唯一的。如果有兩個元素用了相同的名稱,過場會失敗。在動態列表中,你可以用 style 屬性動態設定名稱,例如根據項目 ID 來生成唯一名稱。
這個功能也可以和 CSS Masonry 瀑布流佈局結合使用,在瀑布流的卡片和詳情頁之間做出流暢的過場效果。
MPA 跨頁過場
Cross-Document Transitions 是 View Transitions API 的 Level 2 規範,讓傳統的多頁面網站也能享受過場動畫的好處。
使用方式比 SPA 更簡單。你只需要在 CSS 中加入 @view-transition 規則:@view-transition { navigation: auto; }。這行 CSS 告訴瀏覽器:在同一個 origin 的頁面之間導航時,自動啟用 View Transitions。
接下來,你就可以在兩個頁面中為相對應的元素設定相同的 view-transition-name,瀏覽器會自動處理跨頁的共享元素過場。
MPA 模式有一些限制需要注意:它只在同源頁面之間有效;新頁面必須在一定時間內完成渲染(否則過場會被取消);某些瀏覽器可能需要使用者啟用實驗性功能。
對於使用 SSR(Server-Side Rendering)或 SSG(Static Site Generation)的網站,MPA 模式是一大福音。你不需要改變任何伺服器端邏輯,只需要加幾行 CSS 就能讓整個網站的導航體驗提升一個檔次。
React / Next.js 整合
在 React 專案中使用 View Transitions API,有幾種方式:
方式一:直接使用原生 API。在 React 的狀態更新中包裹 startViewTransition。例如,在路由切換時:先呼叫 document.startViewTransition,在 callback 中使用 React Router 的 navigate 方法。
方式二:使用 React 18.3+ 的 useViewTransition Hook(實驗性)。React 團隊正在開發原生的 View Transitions 支援,讓你可以更自然地在 React 元件中使用。
方式三:在 Next.js 中使用。Next.js 的 App Router 已經開始實驗性地支援 View Transitions。在 next.config.js 中啟用 viewTransitions 功能旗標,然後在 layout.tsx 或 page.tsx 中設定 view-transition-name。
有一個常見的問題是 React 的 concurrent mode 和 View Transitions 的互動。因為 React 可能會在多個渲染週期中更新 DOM,而 View Transitions 需要一個明確的「更新前」和「更新後」的時間點。建議在使用 startViewTransition 時,確保 DOM 更新是同步的(使用 flushSync)。
如果你也在用 CSS 原生功能取代預處理器,可以看看 CSS Mixins 原生混入教學,了解更多 CSS 原生能力的進展。
效能考量
View Transitions API 的效能通常很好,因為動畫是在瀏覽器的合成器(Compositor)層面執行的。但還是有幾點需要注意:
快照成本:瀏覽器在過場開始時需要擷取整個頁面的快照。如果頁面很大或包含大量圖片,快照可能會佔用不少記憶體。在低端裝置上要特別注意。
避免過多的 view-transition-name:每個有 view-transition-name 的元素都會被獨立擷取快照。如果頁面上有太多(比如超過 20 個),可能會影響效能。只對真正需要獨立過場的元素設定名稱。
動畫時長不宜過長:過場動畫的目的是讓導航體驗更流暢,不是讓使用者等待。建議過場時長控制在 200-400ms 之間。超過 500ms 使用者會感覺「卡住」。
考慮 prefers-reduced-motion:有些使用者會在系統設定中開啟「減少動態效果」。用 CSS media query 來偵測這個設定,並在必要時關閉或簡化過場動畫。這不只是好的做法,在某些地區也是無障礙法規的要求。
圖片預載:如果新頁面的內容包含大圖,而這些圖片還沒載入完成,過場動畫可能會在圖片載入過程中顯得不自然。建議搭配 prefetch 或 preload 機制,確保關鍵圖片在過場開始前就已經快取好了。
View Transitions API 代表了 Web 開發的一個重要趨勢:把複雜的互動體驗從 JavaScript 移到瀏覽器原生能力。就像 CSS Grid 取代了 float layout、Intersection Observer 取代了 scroll event listener,View Transitions 正在取代手工打造的頁面過場動畫。如果你正在開發新專案,我強烈建議現在就開始嘗試這個 API。即使只是加上最基本的 cross-fade 效果,也能讓網站的導航體驗明顯提升。
繼續閱讀
CSS Masonry 瀑布流原生佈局教學:不靠 JavaScript 也能做出 Pinterest 排版
CSS Masonry Layout 終於原生支援了!這篇教學帶你用純 CSS 實作瀑布流排版,不再需要 Masonry.js 或其他套件。
相關文章
你可能也喜歡
探索其他領域的精選好文