昨天談無障礙時留了一個尾巴:prefers-reduced-motion。今天正面接住它——動效(Motion)是無障礙這條光譜上最兩極的東西。做錯,大面積視差、無意義彈跳、每次點擊都要看完的過場,會拖慢感受、分散注意,甚至讓有前庭障礙的人當場暈眩想吐;做對,動效變成一種免費的溝通語言,替你引導視線、解釋「這個東西從哪來、要往哪去」、即時回饋「你按到了、系統收到了」。動效不是把介面變漂亮的裝飾層,而是把「狀態轉換」這件抽象的事,翻譯成人腦本來就懂的物理直覺。
📖 學
動效的四個目的:它是功能,不是特效
好的 UI 動畫都在做四件事之一,缺了目的的動畫應該直接刪掉。引導注意力:畫面變化時,動態會自動吸走人眼,用它把使用者的視線帶到剛出現的通知、剛驗證失敗的欄位。表達空間關係與轉場連續性:新頁面從右邊滑進來、詳情從被點的卡片放大展開,是在告訴大腦「這兩個畫面在空間上是相鄰/父子關係」,讓人不會迷失在「我現在在哪、剛才在哪」。提供狀態回饋:按鈕按下去的凹陷、送出後的轉圈、成功的打勾,回答了使用者最焦慮的問題——「我的操作到底有沒有生效」。建立品牌個性:同樣是彈出對話框,俐落的直線淡入和帶點回彈的曲線,傳達完全不同的品牌氣質。Apple 的人機介面指南把這句話講得很白:不要為了動而動,過度或無謂的動畫只會讓人分心、有距離感。
時間 duration 與節奏:快不是唯一目標,「剛好」才是
動畫時長是最容易做錯的參數。太快(低於 100ms)人眼幾乎察覺不到變化,等於沒做;太慢(超過 500ms)每一次互動都在強迫使用者「等動畫演完」,頻繁操作時尤其惱人。業界的共識區間相當一致:一般 UI 轉場約 200–500ms,Apple HIG 建議 100–500ms,NN/g 建議簡單位移 100–300ms、複雜移動約 500ms。更細的兩條經驗法則:進場(enter)可以慢一點、出場(exit)要快——因為新東西出現需要時間讓人看清楚並定位,而要消失的東西已經沒有資訊價值,拖著只是浪費生命;微互動(microinteraction)要更短,像 hover、按鈕回饋這類每天發生上百次的動作,控制在 100–200ms 才不會累積成「這 App 好卡」的體感。時長還要隨移動距離調整:跨越大半個螢幕的元素本來就該花比小圖示更久的時間,這樣才符合物理直覺。
緩動 easing:真實世界沒有等速運動
現實裡沒有任何東西是瞬間達到最高速又瞬間停住的——所有物體都要加速、減速。linear(等速)之所以看起來機械、廉價、假,正是因為它違反這個直覺。緩動曲線用貝茲曲線(cubic-bezier)描述「時間 → 進度」的關係:**ease-out(先快後慢,減速進場)**最常用於元素進場、頁面載入,讓東西快速出現再溫柔停下,感覺靈敏又不突兀;**ease-in(先慢後快,加速離場)**適合元素離開畫面,像被吸走一樣;**ease-in-out(兩頭慢中間快)**適合在畫面內從 A 移到 B 的位移,最自然。Material Design 3 把這套系統化成幾條標準曲線:**Standard(標準)**用於大多數在畫面內開始與結束的轉場;**Decelerate(減速)**用於進入畫面的元素;**Accelerate(加速)**用於離開畫面的元素;**Emphasized(強調)**則是帶點戲劇性的主曲線。記住一個口訣:進場減速、離場加速、留在場內走標準。
轉場與連續性:共享元素轉場,別讓畫面用「切」的
介面最傷神的瞬間,是畫面「啪」地直接換掉,使用者得重新掃視整頁去理解發生了什麼。轉場動畫的核心價值就是維持連續性:讓使用者的注意力有一條可以跟隨的路徑。最強的手法是共享元素轉場(shared element transition)——點清單裡的一張縮圖進入詳情頁,那張圖不是消失再重生,而是平滑地放大、移動到詳情頁的大圖位置。使用者的大腦全程盯著同一個物件,自然理解「這兩個畫面是同一個東西的兩種呈現」,空間隱喻(spatial metaphor)就此建立:抽屜從邊緣滑出、彈窗從觸發它的按鈕長出來,都是在用位置關係說故事。反過來說,無意義的彈跳(bounce)、旋轉、彈簧回彈用在一般生產力工具裡,除了炫技,只會增加認知負擔——動效要服務空間敘事,不是刷存在感。
微互動與效能:60fps 是及格線,不是加分項
微互動(microinteraction)是介面裡那些微小、單一目的的回饋瞬間——開關切換、按讚的愛心、下拉刷新。Dan Saffer 在《Microinteractions》裡拆出經典四段結構:觸發(Trigger)→ 規則(Rules)→ 回饋(Feedback)→ 循環與模式(Loops & Modes)。使用者做了一個動作是觸發,系統依規則運算,用動效/聲音/震動給出回饋,並在重複與長期狀態裡形成模式。動效正是「回饋」這一段的主要語言。但這一切的前提是效能:動畫必須維持 60fps(每幀約 16.7ms 的預算),否則掉幀、卡頓的動畫比沒動畫更傷體驗。關鍵原則是只動 transform 和 opacity——這兩個屬性可以交給 GPU 合成(compositing),不會觸發瀏覽器重新計算版面。反之,動畫 width、height、top、left、margin 這類屬性會觸發 layout(重排) 或 paint(重繪),每一幀都要整頁重算,是卡頓的頭號元凶。想水平移動就用 transform: translateX() 取代改 left,想縮放就用 scale() 取代改 width。
無障礙:動效做錯,會讓人真的生病
承昨天的 prefers-reduced-motion——這不是可有可無的貼心,是實打實的健康問題。有前庭障礙(vestibular disorders)的人,看到大面積的視差滾動、快速縮放或平移的大型物件,可能觸發真實的暈眩、噁心、偏頭痛;閃爍頻率落在特定區間(每秒 3 次以上)甚至可能誘發癲癇(對應 WCAG 2.3.1)。MDN 講得很清楚:prefers-reduced-motion 讓瀏覽器知道使用者偏好「移除、減少或替換」以動態為主的動畫。正確做法不是把動畫全部關掉變成生硬的切換,而是降級:把大幅度的位移、縮放、視差,換成低風險的淡入淡出(opacity 過場)。實作上用媒體查詢包起來:@media (prefers-reduced-motion: reduce) { ... },在裡面把 animation 與 transition 縮到極短或改成單純淡入。原則是:動效預設要克制,把「完整動效」當成一種對「沒有特殊需求的人」的加值,而不是強加給所有人的預設。
🧠 記
- 動效有四個目的:引導注意、表達空間關係與轉場連續性、提供狀態回饋、建立品牌個性——沒目的就刪掉。
- 時長:一般 UI 轉場 200–500ms(HIG 100–500、NN/g 簡單 100–300),進場慢、出場快,微互動更短(100–200ms),並隨移動距離調整。
- 緩動:現實無等速,
linear顯假;進場用 ease-out(減速)、離場用 ease-in(加速)、場內位移用 ease-in-out;Material 對應 Standard / Decelerate / Accelerate。 - 連續性:善用共享元素轉場與空間隱喻,讓注意力有路可跟;避免無意義的彈跳與旋轉。
- 微互動四段(Dan Saffer):觸發 → 規則 → 回饋 → 循環/模式,動效是「回饋」的主要語言。
- 效能:只動
transform/opacity(GPU 合成),避免動width/top/left觸發 layout / paint,守住 60fps(每幀 16.7ms)。 - 無障礙:尊重
prefers-reduced-motion,用淡入淡出降級取代大幅位移/視差/縮放;顧及前庭障礙,避免大面積閃爍(>3Hz 有癲癇風險)。
✍️ 實踐
第一段——健檢一個既有動畫。 挑你手上一個常見的過場(例如彈窗、下拉選單、頁面切換),用 Chrome DevTools 的 Performance 面板錄一次,看它掉不掉幀。如果它在動 width、height、top、left 或 margin,把它改寫成用 transform(translate / scale)+ opacity 達成同樣效果,再錄一次比較幀率。同時量一下它的時長:若超過 500ms 就砍到 300ms 上下、進場用 ease-out、出場改快並用 ease-in,親手感受「快一點」帶來的靈敏感。
第二段——補上減量動效與微互動。 替這個元件加上 @media (prefers-reduced-motion: reduce) 區塊,把大位移降級成純淡入(opacity),然後到系統設定(macOS:輔助使用 → 顯示器 → 減少動態效果)開啟後重整,確認它真的降級了。最後挑一個目前「沒有回饋」的操作——例如送出表單、切換開關——用 Dan Saffer 的四段結構替它設計一個 100–200ms 的微互動回饋,讓使用者一眼確認「系統收到了」。把這兩點寫進你的動效 token 與元件驗收清單,讓動效跟昨天的無障礙一樣,內建在設計系統裡。
🔗 延伸學習
- Easing and duration — Material Design 3 官方動效指南
- Motion — Foundations|Apple Human Interface Guidelines
- prefers-reduced-motion — CSS media feature|MDN Web Docs
- prefers-reduced-motion: Sometimes less movement is more|web.dev
💬 問 AI
把你正在做的一段動畫(CSS/JS 程式碼或口頭描述)丟給 AI,請它同時從「目的、時長、緩動、效能、無障礙」五個面向審查,並給出可直接套用的修法。可複製的 prompt:
你是資深的動效設計(Motion Design)與前端效能審查者。以下是我介面裡的一段動畫:
[貼上你的 CSS/JS 程式碼,或描述這個動畫做什麼、多長、用什麼曲線]
請依下列五個面向逐項審查,並用表格輸出「面向 / 目前狀況 / 問題 / 修正建議(含可套用的程式碼)」:
1. 目的:這個動畫在引導注意、表達空間關係、提供回饋、還是純裝飾?若無明確目的請建議刪除。
2. 時長與節奏:時長是否落在 200–500ms 合理區間?進場/出場是否用了對的快慢?
3. 緩動:easing 曲線是否符合「進場減速、離場加速」?有沒有誤用 linear?
4. 效能:是否只動 transform / opacity?有沒有動到會觸發 layout/paint 的屬性(width、top、left、margin)?如何改寫成 GPU 合成?
5. 無障礙:是否處理了 prefers-reduced-motion?大位移/視差是否降級成淡入?有無 >3Hz 的閃爍風險?
最後,給我一段可直接貼上的 @media (prefers-reduced-motion: reduce) 降級版本。