動畫設計
介面中的動態能解釋發生的事件:元素從何而來、往何處去、按壓是否被感知。除此之外的一切都屬於裝飾,而裝飾有其有限的預算。這項技能幫助你精準運用這份預算:若無此技能,模型會為所有元素套用相同的淡入上移效果。
此技能是自足的。如果同時安裝了 ui-ux(樣式與介面規則)和 front(程式碼與技術棧),它們將相輔相成。
三個先決問題
- 這個動畫的目的是什麼? 是動作的反馈、狀態之間的連結、吸引使用者注意某個重要事物,還是展現品牌性格?如果沒有答案,就不要動畫。
- 使用者會多頻繁看到它? 預算取決於答案(下一節)。
- 專案中已經用了什麼? 查看既有的持續時間、曲線和動畫函式庫,並延續相同的風格。為了一個效果而引入新的函式庫幾乎總是錯誤。
多少動畫才適當
主要規則:動作越頻繁,動畫越少。 第一次觀看時令人驚豔的效果,在第一百次時只會讓人煩躁。
| 使用者觀看頻率 | 應採取的行動 |
|---|---|
| 每天數百次(鍵盤快捷鍵、指令面板、切換分頁) | 無動畫 |
| 每天數十次(選單、工具提示、懸停) | 極快,最多 150 毫秒,或無動畫 |
| 偶爾使用(對話框、側邊面板、通知) | 一般的 200–300 毫秒轉場 |
| 很少或僅一次(引導流程、成功畫面、登陸頁首屏) | 可以較有表現力 |
根據專案類型區分:
- 應用程式(每日使用):節制。控制狀態、圖層進出、流暢的版面變化。所有動畫在 300 毫秒內。沒有使用者操作就不動。
- 展示型頁面(登陸頁、網站、宣傳頁):明顯。首屏一個精心編排的時刻,滾動時區塊揭示,懸停時的活潑細節。其餘部分保持平靜。
每畫面一個表現性時刻,其他地方保持安靜。 所有元素同時動畫,跟完全沒有動畫一樣,都是套版的跡象。
不要為以下情況添加動畫:鍵盤觸發的動作、主題切換、右鍵選單,以及使用者連續執行多次的任何動作。
預設品味
技能擁有者可編輯本節以符合自身偏好。當前請求中使用者所說的話具有優先權。
在展示型表面歡迎使用:
- 滾動揭示 —— 區段與大型物件在滾動到時輕柔出現。僅一次,不重複。
- 滾動驅動場景 —— 固定的區段,滾動控制動畫並解釋產品的某個特性。每頁一或兩個;滾動本身保持正常,絕不劫持其速度和方向。
除非明確要求,否則不使用:
- 發光與漸變邊框 —— 閃爍的輪廓、霓虹光暈、動態漸變背景。強調效果應來自動態與排版,而非光效。
函式庫: 優先使用 CSS;React 中不足時使用 Motion;僅在複雜滾動場景中使用 GSAP。詳細內容見 references/tools.md。
動態風格為「連貫且精準」。
- 應用內流程。 畫面彼此交融而非交換:一個「主角」物件經歷每個步驟,文字透過模糊轉變為文字,僅有變化的部分才改變,新圖層從其來源處生長出來。如果任務包含一系列畫面或狀態,請先閱讀
references/continuity.md並指定一個主角。 - 登陸頁與網站。 全站使用同一條曲線,起始急促、結尾平緩且長,無彈跳;標題逐字組裝;大型物體從模糊中顯現;一個滾動文字場景;全部使用 CSS。包含精確數值的配方在
references/showcase-recipes.md中。
兩者共通之處:模糊與透明度並用作為轉場的材質,進出場重疊而非排隊,無彈跳,以及一條一致的曲線。如果專案風格要求不同的動態風格(如終端機、復古),請參閱 references/patterns.md 中的表格。
持續時間
| 項目 | 持續時間 |
|---|---|
| 按壓、懸停、切換本身的回應 | 100–150 毫秒 |
| 工具提示、下拉選單、小型進場 | 150–200 毫秒 |
| 對話框、面板、抽屜 | 200–300 毫秒 |
| 回應動作的內容變化(價格、計數器、圖表) | 300–500 毫秒 |
| 頁面轉場、大型版面變化 | 300–500 毫秒 |
| 展示型表面上的裝飾性場景,無使用者介入 | 最多 800–1000 毫秒 |
- 退場比進場短約三分之一:正在離開的東西已不再有趣。
- 路徑越長、面積越大,持續時間越長;一個 400 毫秒的小型元素會顯得很遲緩。
- 規則衝突時,較短的勝出。 控制項本身總是在 100–150 毫秒內回應;它所改變的結果可能需要更長時間完成,但使用者不應等待動畫結束才能再次操作。
曲線與彈簧
- 進場 —— ease-out: 起始快速、結尾平緩,給人反應靈敏的感覺。
- 退場 —— 同樣 ease-out,但時間更短。 有些設計系統會為退場使用加速曲線,但其緩慢的起始會感覺像是延遲,因此此處不使用;技能擁有者可更改此規則。
- 在螢幕上從一點移動到另一點 —— ease-in-out。
- 僅持續運動使用線性曲線:旋轉指示器、跑馬燈、進度條。
預設 token:
:root {
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* 主曲線:急促起始,長時間減速 */
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
--duration-fast: 160ms; /* 回應:顏色、透明度 */
--duration-base: 300ms; /* 圖層、控制項的背景與陰影 */
--duration-slow: 450ms; /* 內容融入內容 */
--duration-reveal: 800ms; /* 展示型表面的區塊出現 */
}
整個專案使用同一條曲線:當轉場的每個部分都使用它時,它們會讀起來像同一個動作。使用這條曲線,回應可以持續 200–450 毫秒,但仍感覺即時,因為大多數變化發生在前 100 毫秒內。
彈簧在手勢驅動動畫或動畫可中途中斷(拖曳、面板、列表重新排序)時優於曲線:它們能保留速度且不會產生突跳。彈跳僅用於位移和縮放;顏色和透明度始終為零。明顯的彈跳適合玩樂風格,但在工作工具中會讓人煩躁。
執行規則
- 只動
transform和opacity。 寬度、高度、邊距和位置會觸發佈局重新計算並造成卡頓。要改變大小,請使用scale、FLIP 技術或函式庫的佈局動畫。 - 模糊是被允許的例外。 與透明度結合,
filter: blur()最多 12px 是轉場的標誌性材質,但成本較高:僅應用於小型區塊(標題、圖形、圖示、卡片),切勿應用於整個畫面,並請在手機上測試。 - 進場與退場重疊。 正在離開和正在出現的元素在持續時間的 30–50% 內共存。「先消失,再出現」的順序會破壞連貫性並使時間加倍。
- 僅改變差異部分。 沒有變化的部分(數字、文字、圖示)保持原位。
- 絕不從
scale(0)開始。 現實中沒有任何東西從一個點出現:從 0.9–0.96 加上透明度開始。 transform-origin位於來源處。 選單從其按鈕生長出來,而非從中心。- 按壓:
:active時使用scale(0.97)能產生實體按鈕的感覺。 - 可中斷性。 使用
transition而非@keyframes構建互動式動畫:轉場可以中途反向,關鍵影格則不行。 - 角色優先,時序其次。 當多個元素因同一事件而移動時,指定一個主導元素;其餘為輔助、裝飾或靜態。兩個主導元素是佈局問題,而非動畫問題。
- 每個容器一次進場。 如果面板滑入,其內容應已就位:不要在父元素的進場之上再為子元素添加交錯效果。
- 退場的元素立即釋放其空間, 因此相鄰元素在它淡出時就靠攏,而非之後。
- 退場鏡像進場,且同時發生。 從右邊進來的東西往右邊離開;一組元素同時消失,沒有反向交錯。
- 方向具有意義: 「前進」從右方進場,「後退」從左方進場。
- 交錯: 元素之間間隔 30–80 毫秒,整個級聯不超過 300–400 毫秒;第六或第七個元素之後,其餘元素同時出現。在展示型頁面的首屏,間隔可增至 100–150 毫秒。
- 手勢使用彈簧且絕不阻塞。 元素完全跟隨手指移動,可中途抓取,鬆開後承接手勢的速度。僅在拋擲後才彈跳。
- 工具提示: 第一個有延遲,同一組中的後續工具提示立即出現且無動畫。
- 滾動揭示只發生一次。 一個每次經過都隱藏又重新出現的區塊會讓人疲勞。
- 靜止時頁面應完整。 內容不應依賴腳本是否執行:隱藏的起始狀態應僅在啟用動畫時一併設定,絕不在基礎樣式中。否則,當腳本失敗、在預覽中或螢幕截圖中時,使用者會看到空白畫面。
- 懸停只改變一個屬性, 不要同時改變縮放、抬升和陰影。
will-change—— 僅在動畫期間謹慎使用,不要用在所有東西上。
無障礙設計
這不是選項:螢幕上的動畫會導致某些人頭暈和噁心。
prefers-reduced-motion: reduce: 移除位移、縮放、旋轉、視差和自動播放;保留透明度和顏色的平滑變化。全部關閉會剝奪使用者的反馈。最可靠的方法是只在允許動畫的地方宣告動畫:
.card { transition: opacity var(--duration-base) var(--ease-out), background-color var(--duration-fast); }
@media (prefers-reduced-motion: no-preference) {
.card { transition-property: opacity, background-color, transform; }
.card:hover { transform: translateY(-2px); }
}
- 任何自行移動超過 5 秒的東西(跑馬燈、輪播、背景影片)都必須有暫停按鈕——這是 WCAG 2.2.2 的要求。
- 每秒閃爍不超過三次。
- 大面積的運動(視差、背景縮放)保持小幅度。
- 動畫文字仍應可被螢幕閱讀器閱讀:逐字拆分時,為整體設定
aria-label,並為各個片段設定aria-hidden。
驗證
- 在瀏覽器中觀察動畫,而不僅在程式碼中;如果無法做到,請告知使用者該動畫未經即時驗證。
- 在開發者工具中將動畫速度放慢 4–10 倍:卡頓、錯誤的生長原點和不必要的屬性會變得明顯。
- 快速連續按壓數次:動畫必須能中斷並反向,而不是在佇列中堆疊。
- 在系統中開啟「減少動態效果」,確保介面仍然可用且易於理解。
- 滾動後立即截取的螢幕截圖可能顯示區塊尚未出現的空白區域——這是檢查「靜止時頁面應完整」規則的原因。
審查模式
當被要求評估或修復現有動畫時,請以表格形式報告發現:
| 位置 | 修改前 | 修改後 | 原因 |
|---|---|---|---|
Modal.tsx:18 | scale(0) → 1,500 毫秒,ease-in | scale(0.96) + 透明度,220 毫秒,ease-out | 從一點出現且反應遲緩 |
參考文件
references/continuity.md— 連續動畫:流程的主角、畫面相互融合、數字逐位變化、滾動時折疊;相關技術及其在網頁上的實現方式。閱讀適用於任何畫面或狀態序列。references/choreography.md— 一組元素對單一事件的回應:角色(主導、輔助、裝飾、靜止)、配對內關係(同時、重疊、序列、攜帶)、交錯、方向、退場、中斷。每當多於一個元素移動時閱讀。references/gestures.md— 所有拖曳、滑動和拋擲的內容:手指追蹤、可中斷性、彈簧、速度繼承、動量投影、軟邊界。閱讀適用於面板、輪播、滑桿、拖放。references/showcase-recipes.md— 登陸頁配方,包含精確數值:逐字標題、從模糊中出現、繪製底線、卡片級聯、滾動文字。閱讀適用於網站的首屏和各區段。references/patterns.md— 技術目錄:微互動、進場、數字變化、滾動、頁面轉場、文字;每種技術何時有效、何時有害;各風格的動態特性。references/tools.md— 從 CSS 到 GSAP 的工具階梯,包含程式碼範例和選擇規則。