CSS 的 cubic-bezier() 緩動曲線是由恰好四個數字所定義——x1、y1、x2 和 y2——它們描述介於固定起點 (0, 0) 與固定終點 (1, 1) 之間的兩個中間控制點。這四個數字會直接寫入 transition-timing-function 或 animation-timing-function 屬性中,告訴瀏覽器如何將經過的時間對應到動畫進度上。由於起點與終點永遠不會改變,曲線唯一能調整的只有中間這段旅程的形狀:緩慢的開始、俐落的結束、溫和的減速、越過終點的 overshoot,或在動作開始前回拉的反向 anticipation。CSS 中每一種視覺上的緩動樣式,從熟悉的 ease 關鍵字到自訂的類彈簧動態,都只是這四個座標的不同選擇。因此 cubic-bezier() 是前端開發者在塑造 UI 元素動態手感時最精準的工具。
在使用曲線之前,兩個參考資料是不可或缺的。第一個是 W3C 的 CSS Easing Functions Level 1 規範,其中定義了語法、有效性規則以及關鍵字的對應。第二個是 cubic-bezier() 的 MDN 頁面,記錄了瀏覽器的行為並提供實際範例。這兩個來源在所有會影響你所輸入四個數字的細節上都完全一致。

深入了解 Cubic Bezier 緩動函式
CSS 中的 cubic Bézier 曲線是由四個點之間描繪出的參數式曲線。其中兩個點——(0, 0) 與 (1, 1)——永遠固定不變,分別代表動畫開始的瞬間(時間為零、進度為零)以及動畫結束的瞬間(時間為滿、進度為滿)。其餘兩個點——(x1, y1) 與 (x2, y2)——則是你提供給 cubic-bezier() 的引數值,它們會把曲線拉離一條直線。
視覺上,這兩個控制點的作用就像磁鐵。將控制點拉向左上角,數值就會快速啟動並逐漸收斂。將控制點拉向右下角,數值則會緩慢啟動並逐漸加速。兩個相反方向的控制點會形成 S 形曲線,中段平順而兩端俐落。由於實際上只有每個控制點的 y 座標會改變動畫進度,因此緩動的視覺故事本質上就是 y1 與 y2 的故事。
四個控制點及其限制
CSS Easing Functions Level 1 規範對 x 值要求嚴格,對 y 值則較為寬鬆。兩個 x 座標必須各自落在閉區間 [0, 1] 之中——任何超出此範圍的值都會讓 cubic-bezier() 失效,瀏覽器會改用其預設值。y 座標則可以是任意有限的數字,包括負數以及大於 1 的值。負的 y 會產生 anticipation(動畫值看起來會在向前移動前先往後拉),大於 1 的 y 則會產生 overshoot(數值會越過目標點,再回歸定位)。
五個標準的緩動關鍵字都對應到同一份規範中所定義的特定 cubic-bezier() 值。下表記錄了這些標準的控制點,方便你清楚比對關鍵字與曲線之間的關係。
| CSS 關鍵字 | x1 | y1 | x2 | y2 | 常見感受 |
|---|---|---|---|---|---|
| linear | 0 | 0 | 1 | 1 | 從頭到尾等速 |
| ease | 0.25 | 0.1 | 0.25 | 1 | 柔和的開始,柔軟的結束(預設值) |
| ease-in | 0.42 | 0 | 1 | 1 | 緩慢的開始,加速的結束 |
| ease-out | 0 | 0 | 0.58 | 1 | 快速的開始,減速的結束 |
| ease-in-out | 0.42 | 0 | 0.58 | 1 | 兩端對稱地慢、中段快 |
這些對應關係是規範的一部分,因此任何宣稱與 CSS 相容的產生器都必須與其完全一致。CSS Cubic Bezier Generator 將它們作為參考資料:選擇某個關鍵字就會載入對應的控制點,而顯示出來的宣告式一律顯示全部四個數字,而非隱藏的關鍵字。
使用產生器設計曲線
最快找到可用 cubic-bezier() 值的方式,就是一邊調整四個控制數字,一邊即時獲得視覺回饋。以下工作流程直接在瀏覽器分頁中使用 CSS Cubic Bezier Generator。
- 開啟產生器並選擇起點。如果你已經知道自己想要的感覺類似於某個標準關鍵字,點擊該關鍵字按鈕即可載入其對應的控制點。如果要從頭開始,則可保留輸入框在任合理的預設值。
- 調整四個控制數字。輸入或拖曳 x1、y1、x2 與 y2,朝你想要的形狀調整。請記得規範中的規則:x1 與 x2 必須維持在 0 到 1 之間,而 y1 與 y2 的範圍可以從 −10 到 10。數字會在你輸入時即時更新。
- 檢視圖表。正方形圖表會繪製從左下角固定起點到右上角固定終點的參數式曲線。超出正方形之外的曲線表示 y 值產生了 overshoot 或 anticipation,這可能是刻意設計的。
- 讀取範例表格。表格顯示在輸入時間 0、0.25、0.5、0.75 與 1 時的動畫進度。利用它來確認曲線在四分之一、二分之一與四分之三這些位置,是否產生你所預期的形狀。
- 執行動畫預覽。切換執行預覽,讓一個圓形以目前的曲線在水平方向移動 900 毫秒。重複點擊可比較相同緩動下的正向與反向動作。
- 複製完整的宣告式。使用「複製 CSS」按鈕將 transition-timing-function: cubic-bezier(...); 寫入剪貼簿。宣告式已包含其分號,因此可直接貼入樣式表。
- 在實際元件中測試緩動效果。將該宣告式放進你正在打造的實際 transition 或 animation 中,使用真實的屬性、距離與持續時間。如果動態感覺不對,就回到步驟 2 再次調整。
解讀範例表格與動畫預覽
範例表格回答了光看曲線圖無法回答的問題:在經過特定比例的持續時間時,動畫值實際上已進展了多少?對於每個輸入時間,求解器會找到 x 座標符合該時間的曲線參數,然後在該參數下求取 y 座標。這項區分相當重要,因為 CSS 動畫是依據輸入時間而非曲線參數運行的。具有偏斜 x 控制點的曲線,並不會將一半的動態放在持續時間一半的位置。
動畫預覽採用相同的計算結果曲線,將其套用於 900 毫秒的水平 transition。預覽展示的是時間感,而非實際的執行效能。一旦屬性、距離、持續時間、繪製成本或輸入裝置改變,真實元件的感覺可能會有所不同。請用預覽來比較各曲線彼此之間的差異,並確認動態的大致形狀,接著在實際上線前於真實元件中再次驗證。
如果曲線刻意延伸超出可見的正方形區域,圖表並不代表該值被截斷。正方形維持在穩定的零到一範圍內,是為了方便比較一般曲線。範例表格與移動的圓形都使用實際計算出的緩動結果,因此 overshoot 仍會以大於 1 的 y 值出現在表格中,並在預覽中表現為圓形短暫越過目標位置。
在真實 Transition 中套用時間機函數
一旦預覽中的曲線感覺合適,就把宣告式貼到實際的樣式表中。cubic-bezier() 值會用在 transition-timing-function 中以處理狀態轉換,並用在 animation-timing-function 中以處理關鍵影格動畫。常見的寫法如下:
transition: transform 350ms cubic-bezier(0.22, 0.61, 0.36, 1);
這一行就同時設定了屬性、持續時間與緩動。產生器並不會產生完整的 transition 簡寫、持續時間、延遲,或是動畫的其他部分。這些數值仍由你掌控,這是刻意的設計:16 像素滑動適合的持續時間,幾乎不會是 400 像素滑動適合的持續時間,即使使用相同的曲線也是如此。
在關鍵影格動畫中,相同的值可用於 animation-timing-function。緩動會套用於每一對關鍵影格之間,這可能會產生與單一 transition 相當不同的動態。在動畫上使用自訂曲線時,請預覽整個循環,而非只看第一個片段。
Overshoot、Reduced Motion 與可用曲線
有效的 CSS 並不自動代表合適的 CSS。具有強烈 overshoot 的 cubic-bezier() 可能會讓按鈕看起來像從容器上彈開、短暫露出面板,或顯示原本預期會被裁切的內容。當動態承載意義——確認點擊、表示完成、傳達狀態——過多的 overshoot 會削弱訊息本身。當動態只是裝飾時,overshoot 則可能依情境顯得迷人或令人分心。
請尊重使用者的 reduced-motion 偏好。prefers-reduced-motion 媒體查詢可以將自訂緩動切換回 linear,或是使用非常短的 transition,讓狀態變化在不大規模移動的情況下仍能被理解。有效的曲線並不自動代表它是可存取的、高效的或合適的;它只是數值上格式正確而已。
還有兩個實務上的限制要記得。產生器將 x 輸入限制在閉區間 [0, 1] 內,並接受介於 −10 與 10 之間的有限 y 值;底層的計算會在產生輸出之前獨立重新驗證這些限制。數字只有在宣告式被序列化為文字時,才會取到小數點後三位;在瀏覽器內的計算則保留完整的 JavaScript 精度。所有計算皆在本地進行,不會有任何曲線值、宣告式或互動資料被上傳到任何動畫服務,因此這個工具可放心地用於機密的設計規格與內部色彩系統。
若你在比較各種選項,CSS Create Toggle Button With Exact Geometry 對此有詳細介紹。
若你在比較各種選項,CSS Gradient Colors: From Stops to Production-Ready Code 對此有詳細介紹。
<