结论:x1和x2必须严格在[0,1]内,否则浏览器静默降级为ease;y1/y2可越界实现过冲或回弹,但超出[-0.5,1.5]易致跳变;最常见失效原因是x越界,DevTools中曲线变直线即为信号。

直接说结论:cubic-bezier(x1, y1, x2, y2) 的 x1 和 x2 必须严格落在 [0, 1] 区间内,否则整个函数会被浏览器静默丢弃、降级为 ease;y1 和 y2 可以越界(如负值或大于 1),用来实现过冲或回弹,但超出 [-0.5, 1.5] 就容易在低端设备上跳变或抽搐。
为什么写了cubic-bezier却没生效
最常见原因是 x1 或 x2 超出 [0, 1]。比如 cubic-bezier(-0.1, 0.2, 0.8, 1) 或 cubic-bezier(0.3, 0.1, 1.05, 0.9) ——Chrome、Firefox、Safari 都会直接忽略整条声明,computed 样式里显示的仍是 ease,不报错也不警告。
- 用 Chrome DevTools 的「Animations」面板点开时间函数预览图,如果显示为直线而非曲线,基本就是
x值越界了 - 检查是否被其他 CSS 覆盖:比如父级设置了
transition: all 0.3s ease,子级只写transition-duration没写transition-timing-function,就会继承父级 -
display、z-index、height(未设overflow: hidden)等属性不支持过渡,改了也看不出效果
cubic-bezier(y1/y2越界)怎么用才不出问题
y1 和 y2 越界是实现弹性、过冲的唯一合法手段,但必须控制幅度:
- 想模拟按钮按压回弹:用
cubic-bezier(0.2, 0.7, 0.4, 1.2)——y2 = 1.2是安全上限,再高(如1.6)在 Android WebView 或 Safari 16.3 以下可能首帧猛冲 - 要卡片悬浮带弹性:推荐
cubic-bezier(0.68, -0.55, 0.27, 1.55),y1 = -0.55提供轻微反向启动感,y2 = 1.55是临界值,真机测试过多数机型可稳住 - 避免
y1 < -0.6或y2 > 1.6:数学上可行,但视觉上易变成“抽搐”,尤其在 300ms 以内短动画中
transition 和 @keyframes 里写法差异
语法一样,但作用范围和写法位置完全不同:
立即学习“前端免费学习笔记(深入)”;
-
transition中直接写在简写里:transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);✅ -
@keyframes中不能写进from/to块内部:to { animation-timing-function: cubic-bezier(...); }❌ 无效 - 正确写法是把缓动函数写在调用处:
.box { animation: slide 300ms cubic-bezier(0.2, 0.8, 0.4, 1); }✅ - 想让不同关键帧段落用不同节奏?只能拆成多个独立
@keyframes动画,CSS 不支持单个动画内分段设animation-timing-function
调试时别手敲数字,用工具拖动控制点
人脑很难靠四个小数点想象出曲线形状。Chrome DevTools 的「Animations」面板里点击时间函数右侧小齿轮图标,能直接拖动两个控制点实时预览——这比反复改代码、刷新页面快十倍。
真正需要手写的场景极少:要么是设计稿明确给了 Figma 导出的贝塞尔值,要么是复用已验证过的物理感组合(比如轮盘抽奖用的 cubic-bezier(0.25, 0.1, 0.25, 1))。其余时候,先用 cubic-bezier.com 锁定范围生成,再粘贴进代码,比瞎蒙可靠得多。越界值看着酷,但多数真实 UI 场景里,稳比炫重要。



















