Transitions.dev
十二種可攜式 CSS 過渡效果,每個都以 t-* 選擇器命名,並搭配語義化的 CSS 自訂屬性。直接貼上:貼上程式碼片段,連接文檔中記載的 HTML 鉤子,完成。無框架依賴,無示範專用的標記,每個片段都附帶 prefers-reduced-motion 保護。
快速參考
| 過渡效果 | 使用時機 | 參考文件 |
|---|---|---|
| 卡片縮放 | 當容器佈局狀態改變時,調整其寬度或高度。 | 01-card-resize.md |
| 數字彈入 | 數字更新時,每個數字以模糊滑入的方式重新出現。 | 02-number-pop-in.md |
| 通知徽章 | 將小徽章滑入觸發元素並彈出圓點。 | 03-notification-badge.md |
| 文字交換 | 以模糊的上下過渡在原地交換文字。 | 04-text-states-swap.md |
| 選單下拉 | 開啟一個從觸發元素生長、感知原點位置的下拉選單。 | 05-menu-dropdown.md |
| 模態框開啟/關閉 | 放大模態對話框,關閉時使用較柔和的縮小效果。 | 06-modal.md |
| 面板揭示 | 將面板滑入區域並帶有交錯模糊效果。 | 07-panel-reveal.md |
| 頁面並排 | 在兩個並排頁面之間滑動切換(列表 ↔ 詳細、步驟 1 ↔ 步驟 2)。 | 08-page-side-by-side.md |
| 圖示交換 | 在同一位置交叉淡入淡出兩個圖示,並帶有模糊和縮放。 | 09-icon-swap.md |
| 成功勾選 | 結合淡入、旋轉、上下擺動和路徑描邊繪製來慶祝操作完成。 | 10-success-check.md |
| 頭像群組懸浮 | 一行項目上的距離衰減提升效果,返回時帶有彈性彈跳。 | 11-avatar-group-hover.md |
| 錯誤抖動 | 分段三次貝塞爾曲線抖動,邊框和訊息自動恢復。 | 12-error-state-shake.md |
決策規則
當使用者要求一個過渡效果時,先比對可見的 UI 元素,再比對動詞:
- 觸發元素 + 浮在上方的小圓點 → 通知徽章。
- 觸發元素 + 從其生長的表面 → 下拉選單(固定定位、感知原點)或模態框(居中、無錨點)。
- 滑入頁面某個區域的表面 → 面板揭示。
- 兩個畫面,列表 ↔ 詳細 或 步驟 1 ↔ 步驟 2 → 頁面並排。
- 元素改變寬度或高度 → 卡片縮放。
- 元素的文字內容在原地改變 → 文字交換。
- 同一位置的兩個圖示 → 圖示交換。
- 數字更新 → 數字彈入。
- 確認 / 成功 /「完成」的時刻(勾選、付款處理、檔案上傳) → 成功勾選。
- 水平堆疊中的項目懸浮(頭像、晶片、分段按鈕、標籤膠囊) → 頭像群組懸浮。
- 表單驗證錯誤 /「這錯了」的回饋(無效欄位、錯誤 PIN、重複名稱) → 錯誤抖動。
- 沒有明確匹配 → 回退到
transitions reveal讓使用者選擇。不要猜測。
如果兩個過渡效果都可能適用,選擇開銷較低的那個(卡片縮放優先於面板揭示,下拉選單優先於模態框,成功勾選優先於完整的模態慶祝),除非設計明確需要較重的表面。成功勾選僅包含動畫——如果還需要從旋轉器切換到勾選標記,請搭配圖示交換。
指令
此技能公開三個命名動詞,除了直接的過渡請求外,代理也應識別它們。每個指令都以 transitions 開頭,因此呼叫不會與同專案中其他技能安裝的動詞衝突。
transitions reveal — 列出所有過渡效果
觸發短語: transitions reveal、「顯示過渡效果」、「列出所有過渡」、「這個技能有哪些過渡」、「顯示過渡目錄」。
行為: 以編號純文字列表的形式印出十二個過渡效果——名稱、一行摘要和對應的參考文件名。重複使用上方 ## 快速參考 中的行;不要發明新的副本。無需存取專案。
transitions review — 審計專案中的適用點
觸發短語: transitions review、「審查我的專案」、「審計我的動畫」、「哪里 transitions.dev 能幫上忙」、「尋找使用此技能的地方」。
行為:
- 搜尋工作區中的指示:
transition:宣告、@keyframes、樣式檔案中硬編碼的ms/s持續時間、符合十一種決策規則模式的元件(模態框、下拉選單、徽章……)。 - 對每個命中點,與決策規則進行比對,並選出單一最適合的過渡效果。
- 輸出按文件分組的編號列表:
path/to/Component.tsx:L42——看起來像下拉選單開啟,建議使用 menu-dropdown(05-menu-dropdown.md)。- 跳過已經使用
t-*類別的臨時過渡。
- 不要編輯任何內容。以「對任一行的內容執行
transitions apply以安裝建議的過渡。」結尾。
transitions apply — 安裝最適合的過渡效果
觸發短語: transitions apply、「在此處應用過渡」、「新增正確的過渡」、「在此安裝 transitions-dev」、「修復此元素的動畫」。
行為:
- 讀取上下文:目前開啟的檔案、最靠近游標的元素、周圍的 CSS / JSX。如果使用者明確指定了過渡名稱(例如
transitions apply menu-dropdown),則使用它。 - 對該上下文執行
## 決策規則中的規則,並選出一個過渡效果。如果兩個都可能適合,選擇開銷較低的那個(與現有規則相同的決勝條件)。 - 提出一行提案:「我建議在此處使用 menu-dropdown,因為該元素從觸發點開啟且是固定定位。確認安裝?」。
- 確認後,逐字遵循
## 輸出格式中現有的五步驟流程(根區塊、程式碼片段、鉤子、減少動作保護、必要時 JS 編排)。 - 如果代理無法有把握地選出單一過渡效果,則回退到
transitions reveal並請使用者選擇。
通用安裝
將這個 :root 區塊放入你的專案一次。每個過渡片段都從這些語義名稱中讀取——之後無需追蹤單個元件的值。
/* transitions-dev — 將此 :root 區塊複製到你的專案一次。
每個過渡片段都從這些語義名稱中讀取。 */
:root {
/* 卡片縮放 */
--resize-dur: 300ms;
--resize-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* 數字彈入 */
--digit-dur: 500ms;
--digit-distance: 8px;
--digit-stagger: 70ms;
--digit-blur: 2px;
--digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
--digit-dir-x: 0;
--digit-dir-y: 1;
/* 通知徽章 */
--badge-slide-dur: 260ms;
--badge-pop-dur: 500ms;
--badge-pop-close-dur: 180ms;
--badge-fade-dur: 400ms;
--badge-fade-close-dur: 180ms;
--badge-blur: 2px;
--badge-offset-x: -8.2px;
--badge-offset-y: 12.4px;
--badge-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
--badge-pop-ease: cubic-bezier(0.34, 1.36, 0.64, 1);
--badge-close-ease: cubic-bezier(0.4, 0, 0.2, 1);
/* 文字交換 */
--text-swap-dur: 150ms;
--text-swap-translate-y: 4px;
--text-swap-blur: 2px;
--text-swap-ease: ease-in-out;
/* 選單下拉 */
--dropdown-open-dur: 250ms;
--dropdown-close-dur: 150ms;
--dropdown-pre-scale: 0.97;
--dropdown-closing-scale: 0.99;
--dropdown-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* 模態框開啟/關閉 */
--modal-open-dur: 250ms;
--modal-close-dur: 150ms;
--modal-scale: 0.96;
--modal-scale-close: 0.96;
--modal-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* 面板揭示 */
--panel-open-dur: 400ms;
--panel-close-dur: 350ms;
--panel-translate-y: 100px;
--panel-blur: 2px;
--panel-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* 頁面並排 */
--page-slide-dur: 200ms;
--page-fade-dur: 200ms;
--page-slide-distance: 8px;
--page-blur: 3px;
--page-stagger: 0ms;
--page-exit-enabled: 1;
--page-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
--page-fade-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* 圖示交換 */
--icon-swap-dur: 200ms;
--icon-swap-blur: 2px;
--icon-swap-start-scale: 0.25;
--icon-swap-ease: ease-in-out;
/* 成功勾選 */
--check-opacity-dur: 550ms;
--check-rotate-dur: 550ms;
--check-rotate-from: 80deg;
--check-bob-dur: 450ms;
--check-y-amount: 40px;
--check-blur-dur: 500ms;
--check-blur-from: 10px;
--check-path-dur: 550ms;
--check-path-delay: 80ms;
--check-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
--check-ease-opacity: cubic-bezier(0.22, 1, 0.36, 1);
--check-ease-rotate: cubic-bezier(0.22, 1, 0.36, 1);
--check-ease-bob: cubic-bezier(0.34, 1.35, 0.64, 1);
--check-ease-path: cubic-bezier(0.22, 1, 0.36, 1);
/* 頭像群組懸浮 */
--avatar-lift: -4px;
--avatar-dur: 320ms;
--avatar-scale: 1.05;
--avatar-falloff: 0.45;
--avatar-ease-in: cubic-bezier(0.22, 1, 0.36, 1);
--avatar-ease-out: cubic-bezier(0.34, 3.85, 0.64, 1);
/* 錯誤抖動 */
--shake-distance: 6px;
--shake-overshoot: 4px;
--shake-dur-a: 80ms;
--shake-dur-b: 60ms;
--shake-ease: cubic-bezier(0.22, 1, 0.36, 1);
--revert-hold: 3000ms;
--revert-dur: 280ms;
}
在 transitions.dev(https://transitions.dev)的即時示範中所使用的 --pX-* 源代碼記號故意不在此處導出。可調整的值已重新命名為語義名稱(--badge-*、--dropdown-*、--modal-*……),讓使用者擁有設計詞彙的所有權。
輸出格式
將過渡效果插入使用者的專案時:
- 將上述
:root區塊新增到使用者的全域樣式表中,但僅當它尚未存在時。如果使用者已經導入通用安裝區塊一次,請不要重複新增。 - 從相關參考文件中逐字貼上所選過渡效果的 CSS。不要重寫選擇器,不要將過渡壓縮為縮寫,不要移除
will-change。這些代碼片段是經過調整和測試的。 - 連接文檔中記載的 HTML 鉤子——類別名稱(
.t-dropdown、.t-modal、.t-success-check、.t-avatar、.t-input……)和狀態屬性(data-open、data-state、data-page、.is-open、.is-closing、.is-exit、.is-enter-start、.is-animating、.is-error、.is-shaking)。 - **保留
@media (prefers-reduced-motion: reduce)區塊。**每個片段都附帶一個。移除它會使元件無法通過無障礙審計。 - 對於需要 JS 的過渡效果(下拉選單、模態框、文字交換、數字彈入、頁面滑動、成功勾選、頭像群組懸浮、錯誤抖動),從參考文件中複製小型編排片段,並將選擇器調整為使用者的 DOM。保留計時讀取(
getComputedStyle(...)getPropertyValue("--…")),以便持續時間與:root值保持同步。
保持差異小巧:僅編輯引入過渡效果所需的檔案。不要重新命名使用者現有的變數,不要重新格式化不相關的 CSS,不要引入動畫庫。
應避免的常見錯誤
- 移除關閉狀態類別清理——在下拉選單/模態框中,沒有移除
.is-closing的setTimeout,下次開啟時會從關閉縮放狀態跳躍,而不是從靜止的開啟前縮放狀態。 - 忘記重排——在文字交換、數字彈入、成功勾選重播和錯誤抖動中,在類別/屬性移除和重新新增之間使用
void el.offsetWidth(或offsetHeight)是保證動畫重播的關鍵。 - 動畫化單個容器而不是內部元件——對於徽章,動畫化圓點,而不是觸發元素;對於頁面滑動,動畫化頁面部分,而不是容器。
- 將
transition: …替換為transition: all——每個片段都刻意列舉了確切的屬性,以防止不相關的樣式變化免費搭載。 - 硬編碼成功勾選的
stroke-dasharray——片段以20作為佔位符。將其替換為path.getTotalLength()向上取整加 1,以適應你的路徑,否則描邊會提前顯示或過度繪製。 - 在 CSS 中設定頭像群組懸浮的
transition-timing-function——必須在 JS 中、在--shift/--scale-active寫入之前內聯設定,以便彈出的 ease-out 僅在mouseleave時生效。 - 將錯誤抖動的
.is-error和.is-shaking混合為一個類別——保持它們正交,這樣抖動可以重播(移除 → 重排 → 重新新增),而不會閃爍整個錯誤狀態。
參考文件
- 01-card-resize.md — 卡片縮放
- 02-number-pop-in.md — 數字彈入
- 03-notification-badge.md — 通知徽章
- 04-text-states-swap.md — 文字交換
- 05-menu-dropdown.md — 選單下拉
- 06-modal.md — 模態框開啟/關閉
- 07-panel-reveal.md — 面板揭示
- 08-page-side-by-side.md — 頁面並排
- 09-icon-swap.md — 圖示交換
- 10-success-check.md — 成功勾選
- 11-avatar-group-hover.md — 頭像群組懸浮
- 12-error-state-shake.md — 錯誤抖動
- _root.css — 獨立的通用安裝區塊,可直接導入。