CSS 的 cubic-bezier() 緩動函式是由恰好四個數字所定義 —— x1、y1、x2 和 y2 —— 而決定曲線是否有效、是否易讀、以及是否符合預期行為的細節,在於每個座標的意義、CSS 對每個座標所允許的範圍,以及求解器對所產生的參數曲線進行取樣的方式。第一個和第三個數字描述輸入時間,必須維持在從 0 到 1 的閉區間內。第二個和第四個數字描述輸出進度,可以合法地超出該區間,這就是 CSS 過渡中預期效果(anticipation)與 overshoot(超調)出現的原因。由於 CSS 以 x 軸動畫化經過的時間,因此在持續時間 50% 時使用者所看到的值,在參數意義上並非 t 等於 0.5 時的曲線值,而是在 x 座標等於 0.5 的那個 t 上的 y 值。將這一切串連在一起的細節就是求解器 —— 一個由有界牛頓迭代(Newton iterations)收尾於二分法(bisection)所組成的混合演算法,CSS Cubic Bezier Generator 在本機端執行此演算法,讓取樣表與 Run 預覽能與你所輸入的四個座標保持一致。

what details matter when i generate css cubic bezier
產生 CSS Cubic Bezier 時哪些細節很重要

定義每一條曲線的四個數字

CSS 中的 cubic-bezier 緩動是一條單一的參數曲線,永遠從點 (0, 0) 出發,也永遠在點 (1, 1) 結束。這兩個端點是由規格所固定、無法編輯的,因為每個過渡都必須從零進度開始、並以完整進度結束。你所能控制的是兩個中間控制點:(x1, y1) 和 (x2, y2)。拉動其中任一點,動畫值在 0 與 1 之間所走的路徑便會隨之彎曲,這也正是為何單一一行 cubic-bezier() 宣告,就能從同樣的四個數字產生 ease、snap、drift、anticipation 或 overshoot 等效果。

CSS 語法直接反映了這個結構。一個有效的宣告看起來像 cubic-bezier(0.25, 0.1, 0.25, 1),所有四個座標依序排列在括號內。任何缺漏、在括號之外的內容,或任何非數值的詞元,都屬於語法錯誤而非風格選擇,瀏覽器會靜默地 fallback 到預設的時間曲線。CSS Cubic Bezier Generator 會寫出完整的宣告,包含其尾端的分號,讓你所複製的內容就是剖析器所預期的內容。

Cubic Bezier 圖形上 x 與 y 所代表的意義

圖形在其兩個座標軸上繪製了兩個不同的量,把它們搞混是自訂緩動最常見的挫折來源。水平的 x 軸是經過的時間,經過正規化使過渡的起始點落在 0,結束點落在 1。垂直的 y 軸是動畫進度,同樣從 0(尚未移動)正規化到 1(最終位置)。將曲線上的一個點解讀為「在這個時間比例時,值已進展了該比例」是正確的;將其解讀為「這是曲線的局部 t 參數」則是陷阱。

曲線本身是某個局部 t 中的參數函式,t 從 0 跑到 1,且與時間無關。CSS 並非動畫化 t,而是動畫化對應於當前 x 值的 y 值。當 x1 與 x2 差距很大時,產生 x 等於 0.5 的那個參數 t 可能落在完全不同的局部位置,因此在你的持續時間中點處的可見值,可能遠高於或遠低於 0.5。這就是為什麼即便時間正好在中點,尖銳曲線的緩動在中段總是感覺不平均。

有效範圍以及為何 Overshoot 仍算有效

W3C CSS Easing Functions Level 1 規定,當任一個 x 控制座標落在從 0 到 1 的閉區間之外時,cubic-bezier 值即為無效。瀏覽器會丟棄無效的時間曲線並 fallback 到預設曲線,這意味著像 x1 = 1.05 這樣的打字錯誤,會靜默地將你的自訂緩動變成別的東西。CSS Easing Functions Level 1 規格是此規則的權威來源,而產生器在輸入層強制執行此規則,讓無效的 x 值無法進入序列化輸出。

y 座標並不受相同的範圍限制。y1 與 y2 可以是負值、可以大於 1,也可以是介面所接受的任何有限數值,產生器將其上限設為負十到十之間。負的 y 會產生 anticipation:動畫值在開始時先向後移動,再向前移動。大於 1 的 y 會產生 overshoot:動畫值超過最終位置,再回歸定位。這兩種行為都是有效的 CSS,也對像是按鈕按下或彈簧式入場等場景很有用,但在上線前應該以視覺方式檢查,因為它們也可能將元素推出其容器,或裁切掉設計原本預期保持裁切的內容。這個邊角案例的完整說明請見 CSS cubic-bezier() 中的 y1 或 y2 可以超出 0–1 範圍嗎?。

如何以三個步驟產生並驗證一條曲線

  1. 挑選一個起點。若你想要一個已知可用的基準,可從五個標準緩動關鍵字中選擇一個;若要從零設計自訂曲線,則輸入四個明確的控制座標 (x1, y1, x2, y2)。x 輸入在你輸入時會被限制在 CSS 所允許的 0 到 1 範圍內;y 輸入接受介於負十到十之間的有限值,以便仍可達到 anticipation 與 overshoot。
  2. 檢視曲線與取樣。觀察方形圖表上的形狀,讀取位於 0、0.25、0.5、0.75 和 1 的五個輸入到輸出取樣,以得知那些時間點上的精確數值進度,並切換 Run 預覽,觀看一個圓形在 900 毫秒的 transform 過渡中穿越預覽區域。預覽使用的是與產生器輸出相同的緩動字串,因此你在預覽中看到的時間就是瀏覽器將使用的時間。
  3. 複製並在實際元件中測試。使用 Copy CSS 控制項將完整的 transition-timing-function 宣告(連同其分號)寫到剪貼簿。將它套用到你實際要動畫化的屬性、距離與持續時間上,並在認定曲線完成前,先在 reduced-motion 與 focus 條件下確認動作讀起來正確。

正確讀取取樣表與 Run 預覽

取樣表回答了一個光看控制點圖無法回答的問題:當某個時間比例已經過去時,動畫值已經進展了多少。對於位於 0、0.25、0.5、0.75 和 1 的每一個輸入,求解器會找出其 x 座標符合所要求的輸入比例的曲線參數,然後在該參數下求取 y 值。求解器先使用有界牛頓迭代,必要時再以二分法收尾,這讓結果在 x 上保持單調,並避免將局部參數 t 當成經過時間的常見錯誤 —— 即使在控制點讓兩者不同的情況下也是如此。

因此,數值取樣忠實呈現了曲線。一個顯示輸入 0.5 配對輸出 0.92 的列,代表動畫在持續時間中點時已進展到最終位置的 92%,這正是強烈的 ease-out 曲線該有的表現,也是眼睛在 Run 預覽中能直接感受到的。重複點擊 Run 可以觀察正向與反向的動作,這在像 ease-in-out 這種對稱預設中特別有用 —— 因為其反向路徑會鏡像正向路徑,任一方向的錯誤在感覺上很明顯,但在靜態數字上卻難以察覺。

關鍵字對應的 cubic-bezier()特性
linearcubic-bezier(0, 0, 1, 1)在整個持續時間內維持等速。
easecubic-bezier(0.25, 0.1, 0.25, 1)CSS 預設緩動;溫和加速、輕柔減速。
ease-incubic-bezier(0.42, 0, 1, 1)緩慢啟動,接近尾聲時加速。
ease-outcubic-bezier(0, 0, 0.58, 1)快速啟動,逐漸減速進入最終位置。
ease-in-outcubic-bezier(0.42, 0, 0.58, 1)兩端緩慢,中點最快。

關鍵字預設與明確座標的比較

選擇關鍵字並不會直接輸出該關鍵字本身。可見的宣告永遠會列出所有四個數字,即使曲線是來自 Linear、Ease、Ease-In、Ease-Out 或 Ease-In-Out 按鈕。這個選擇很重要,因為它讓輸出可被記錄、可在不同版本間比較,並且可在沒有隱藏預設值的情況下進行修改:你可以複製這四個數字、手動微調其中一個、再貼回產生器,預覽會立即更新。

序列化輸出中的數字只有在離開計算機時才會四捨五入到小數三位;取樣與求解器在整個過程中都保留完整的 JavaScript 數值精度。因此,一個在內部運算為 0.3333333... 的控制座標,在複製內容中會顯示為 0.333,但取樣表與 Run 預覽仍會反映未四捨五入的值。在協作情境中,把四捨五入後的文字當成工作值是個值得戒除的習慣 —— 兩位設計師在不同的階段進行四捨五入,可能會產生看起來相同、實際動作卻略有不同的宣告。MDN 的 cubic-bezier() 參考文件 從瀏覽器端說明了同樣的四捨五入行為,當宣告看起來正確但動作卻不對勁時,是個有用的交叉驗證。

上線時的無障礙與動畫考量

CSS 允許那些技術上有效、但實務上令人不悅或困惑的曲線。大的 overshoot 可能讓控制項看起來像是反方向移動、離開其容器,或顯示出原本預期保持隱藏的內容。在正、負 y 值之間的快速振盪也可能讓有前庭敏感性的觀察者感到不適,即使該曲線本身滿足規格中的每一項限制。無障礙的底線與任何過渡相同:讓重要的狀態變更在沒有動畫的情況下也可被理解、遵守 prefers-reduced-motion,並確認在元素正在動的期間,焦點與指標行為仍然可預期。

產生器只專注於單一的 cubic-bezier 時間函式,僅止於此。它不會產生關鍵影格(keyframes)、彈簧物理、linear() 停駐點清單、steps()、持續時間、延遲、迭代次數,或是完整的 transition 簡寫。這個範圍是特性而非限制:輸出保持單行可審核、且易於與 W3C 規格進行比對。動畫所需要的其他項目,例如持續時間、距離,以及被動畫化的屬性,仍然必須在周圍的 CSS 中選擇,讓緩動能落在一個能發揮作用的環境中,而不是與周圍的動作互相牴觸。

想進一步了解,請參閱 產生 CSS Toggle Switch 時哪些細節很重要。