Motion 是做什麼的?
Motion 解釋變化並確認輸入。如果兩者皆非,則為裝飾,需要理由。
1. 應該加入動畫嗎?
| 使用者看見的頻率 | 決定 |
|---|---|
| 每天超過 100 次(快捷鍵、面板切換、打字) | 永不動畫 |
| 數十次(懸停、列表導航、標籤頁) | 微小或無動畫(150ms 內的顏色/透明度變化) |
| 偶爾(模態框、抽屜、訊息提示、下拉選單) | 標準轉場 |
| 罕見(新手引導、成功提示、初次訪問的主視覺) | 可加入驚喜效果 |
永遠不要為鍵盤觸發的操作加入動畫。
2. 緩動函數
- 進入或退出:強烈 ease-out
cubic-bezier(.23, 1, .32, 1)。 - 螢幕上移動:ease-in-out
cubic-bezier(.77, 0, .175, 1)。 - 抽屜/面板:
cubic-bezier(.32, .72, 0, 1)。 - 顏色/懸停:
ease。持續運動(跑馬燈、進度條):linear。 - UI 中絕不使用
ease-in;在用戶注視的瞬間會感覺延遲。
3. 持續時間
按壓 100-160ms · 工具提示 125-200ms · 下拉選單 150-250ms · 模態框/抽屜 200-400ms · 行銷主視覺最多 800ms。退出速度比進入速度快約 20%。UI 動畫保持 300ms 以內。
4. 實作規則
- 僅動畫
transform和opacity。永遠不要動畫width、height、top、left或transition: all。 - 任何元素不要從
scale(0)開始;從scale(.95)+opacity: 0開始。 - 彈出視窗和選單從觸發元素縮放(
transform-origin設定在觸發元素上)。模態框保持居中。 - 按鈕:
:active { transform: scale(.97) },配合 120ms 轉場。 - 工具提示:第一個延遲約 400ms;相鄰的工具提示立即開啟。
- 列表交錯動畫:每個項目間隔 30-50ms,總時間不超過 400ms。
- 捲動揭示:每頁最多一個,小距離(8-16px),只執行一次。不要每個區塊都使用。
- 彈簧效果(Motion/Framer、React Spring)用於拖曳、手勢和中斷式移動:
{ type: "spring", duration: .4, bounce: .15 }。反彈值保持 0.1-0.3,僅在具有玩樂感的表面上使用。 - 偏好使用 CSS 轉場和
@starting-style處理簡單的進入/退出;使用 View Transitions API 處理頁面/狀態變形;只有在需要手勢或序列時才使用 JS 函式庫。
5. 減少動畫效果(必備)
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: .01ms !important;
animation-iteration-count: 1 !important;
transition-duration: .01ms !important;
scroll-behavior: auto !important;
}
}
保留透明度變化和狀態顏色;移除移動、視差和搖晃效果。
審查格式
審查動畫程式碼時,以表格回覆:| Before | After | Why |,每個問題一行。