cubic-bezier() 的四个参数是贝塞尔曲线两个控制点的坐标(x1, y1, x2, y2),均须在 [0,1] 范围内;x 超出会导致函数失效,y 超出可能引发反向运动或降级,需严格校验并真机测试。

什么是 cubic-bezier() 的四个参数
cubic-bezier() 接收四个数字:x1, y1, x2, y2,它们不是时间或像素值,而是贝塞尔曲线控制点的坐标。前两个是第一个控制点,后两个是第二个控制点,所有值必须在 0 到 1 之间(cubic-bezier(0.25, 0.1, 0.25, 1) 合法;cubic-bezier(-0.1, 0, 1.2, 0.8) 在部分浏览器中会被静默截断或报错)。
- 超出 [0,1] 的 x 值(如
x1 = -0.1或x2 = 1.5)会导致 Chrome/Firefox 忽略整个函数,回退到ease - y 值超出范围不会导致失效,但可能产生“反向运动”(比如
y1 = 2让动画先猛往上冲再回落) - 控制点越靠近左下和右上(如
cubic-bezier(0.42, 0, 0.58, 1)),过渡越接近线性;越靠近左上或右下,缓动越极端
怎么调试 cubic-bezier() 不生效
常见现象:写了 transition: all 0.3s cubic-bezier(0.1, 0.8, 0.9, 0.2);,但动画看起来还是默认的 ease。
- 检查是否被其他 CSS 覆盖:用浏览器开发者工具看 computed 样式里
transition-timing-function是否真显示你写的值 - 确认属性确实支持过渡:比如
display、z-index无法过渡,改了也看不出效果 - 避免在简写
transition中混用多个 timing function:transition: width 0.3s, height 0.3s ease-in;是合法的,但transition: width 0.3s cubic-bezier(...), height 0.3s;会让后者继承前者的 timing function,容易误判 - Safari 对负 y 值更敏感,
cubic-bezier(0.2, -0.3, 0.8, 1.2)在 Safari 可能直接降级为linear
哪些场景适合手写 cubic-bezier() 而不是用关键字
ease、ease-in-out 等关键字本质就是预设的 cubic-bezier(),比如 ease ≡ cubic-bezier(0.25, 0.1, 0.25, 1)。自定义只在以下情况真正必要:
- 需要精确匹配设计稿里的动效节奏(比如 Figma 动效面板导出的贝塞尔值)
- 实现物理感反馈:按钮按压用
cubic-bezier(0.2, 0.7, 0.4, 1.2)模拟弹性回弹 - 微交互一致性:比如所有 hover 缩放统一用
cubic-bezier(0.34, 1.56, 0.64, 1),避免ease-in-out在不同时长下节奏失真 - 性能敏感路径:比起 JS 控制帧率,纯 CSS
cubic-bezier()由合成器处理,只要不触发 layout 就很稳
别忽略的兼容性和数值陷阱
IE 10+ 支持 cubic-bezier(),但不支持 steps() 和 spring() 这类新函数;而 Safari 16.4 之前对超限 y 值的处理不一致。
立即学习“前端免费学习笔记(深入)”;
- 不要用小数点后太多位(如
0.234567):CSS 解析器会四舍五入,实际生效可能是0.235,没必要 - 避免 x1 == x2(如
cubic-bezier(0.3, 0, 0.3, 1)):这会让曲线退化成一条竖线,浏览器行为未定义,Chrome 可能卡顿 - 如果用 CSS-in-JS(如 Emotion、Styled Components),确保模板字符串没意外转义:
<code>transition: all 0.2s ${bezier}比<code>transition: all 0.2s ${bezier.toString()}更安全,后者可能把数组转成"0.2,0.1,0.8,0.9"导致语法错误
手写 cubic-bezier() 最容易栽在“以为值随便写,浏览器会容错”,其实它对输入非常较真——x 越界就丢,y 越界就乱,写完务必在目标浏览器里真机点一点。










