cubic-bezier()参数越界会静默降级为ease,y1或y2超出[0,1]即失效;x1/x2略超可能保留但不跨浏览器一致;transition中须写在简写属性内,@keyframes中须写在animation调用处而非关键帧内。

cubic-bezier() 参数越界会静默失效,不是报错
浏览器对 cubic-bezier(x1, y1, x2, y2) 的容错逻辑很隐蔽:只要 y1 或 y2 超出 [0, 1] 区间,整条曲线就被丢弃,降级为 ease;x1 和 x2 略超(如 1.05)通常能保留,但不保证跨浏览器一致。
常见错误现象:
- 写成
cubic-bezier(0.3, -0.2, 0.7, 1.4),结果动画开头猛冲、结尾卡顿,像没加缓动 - 用设计工具导出的“弹性曲线”直接粘贴进 CSS,却在 Safari 上完全线性
调试建议:
- 打开 Chrome DevTools → Animations 面板 → 点击时间函数预览图,若显示为直线而非曲线,说明已降级
- 坚持用 cubic-bezier.com 这类工具生成,它默认锁死输入范围
transition 和 @keyframes 中 cubic-bezier() 的写法位置不同
cubic-bezier() 在两种场景下不能混用——不是语法不支持,而是作用域规则不同。
立即学习“前端免费学习笔记(深入)”;
transition 场景下必须写在简写属性里:
/* ✅ 正确:写在 transition 属性中 */
.element {
transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);
}@keyframes 场景下不能塞进 from/to 块内:
/* ❌ 错误:animation-timing-function 不允许出现在关键帧内部 */
@keyframes slide {
from { opacity: 0; }
to {
opacity: 1;
animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1); /* 无效 */
}
}
<p>/<em> ✅ 正确:写在调用 animation 的元素上 </em>/
.box { animation: slide 300ms cubic-bezier(0.2, 0.8, 0.4, 1); }想让动画有弹性,y 值可以略超 1,但别乱调
真正起弹性/过冲效果的是 y2 > 1(比如 1.2~1.5),不是越大越好。数学上它会让曲线在终点前“冲过头”,再折返,但人眼只认节奏感。
安全微调策略:
- 要“轻盈入场”:把
y1设为0.05~0.2,避免0(会变ease-in) - 要“柔和收尾带点回弹”:设
y2为1.2~1.4,同时x2别超过0.9,否则回弹延迟太长 - 别碰
y1 或 <code>y2 > 1.6:低端安卓机上插值计算可能抖动,不是渲染掉帧,是调度抖动
示例(按钮点击缩放反馈):
.btn:active {
transform: scale(0.95);
transition: transform 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
}animation-timing-function 本身不伤性能,但曲线太陡会暴露硬件短板
这个属性只影响重绘节奏,不触发重排,只要动画属性本身是合成层友好型(transform、opacity),换任何曲线都不会掉帧。
真正影响体验的是人眼敏感度和设备能力:
-
cubic-bezier(0.4, 0, 0.2, 1)这类平滑缓动,在所有设备上都稳 -
cubic-bezier(0.68, -0.55, 0.27, 1.55)(Material Design 推荐)在部分低端安卓机上偶现卡顿,主因是 JS 主线程插值调度的小抖动,非 GPU 渲染问题 - 如果动画持续时间短于 200ms,用复杂贝塞尔曲线反而显得突兀,不如直接
ease-out
复杂点在于:曲线参数没有绝对“正确”,只有“在当前设备 + 当前时长 + 当前语义下是否自然”。最常被忽略的是——先确认动画时长是否合理,再调曲线。


















