cubic-bezier()、linear、ease、ease-in、ease-out、ease-in-out 六种为全浏览器支持的标准值;ease 是默认值,等价于 cubic-bezier(0.25, 0.1, 0.25, 1),非匀速而是先慢后快再慢。

animation-timing-function 支持哪些预设值
直接说结论:cubic-bezier()、linear、ease、ease-in、ease-out、ease-in-out 这六种是所有浏览器都支持的标准值。其中 ease 是默认值,实际等价于 cubic-bezier(0.25, 0.1, 0.25, 1),不是“匀速”,而是先慢后快再慢。
常见错误是以为 ease 就是“平滑过渡”,结果动画开头顿一下、结尾又拖尾,尤其在按钮 hover 或 modal 弹出时特别明显。
-
linear真正匀速,但人眼会觉得“机械”“生硬”,适合进度条或纯数据可视化场景 -
ease-in开头极慢,适合“浮现感”弱的入场(比如淡入但不强调动势) -
ease-out结尾减速明显,常被误用于“收尾自然”,但若持续时间短(
用 cubic-bezier() 自定义速度曲线时怎么调才不翻车
cubic-bezier(x1, y1, x2, y2) 的四个参数不是像素或毫秒,而是贝塞尔曲线控制点的坐标,x 必须在 [0,1] 区间,y 可以超出(比如负值或大于 1),用来实现“回弹”或“过冲”效果。
最容易踩的坑是:把 y 值设得太大(如 cubic-bezier(0.1, 3, 0.8, -2)),导致动画在中间阶段猛冲再急刹,视觉上像抽搐——这不是 bug,是曲线数学特性决定的,但多数 UI 场景不需要这么激进。
立即学习“前端免费学习笔记(深入)”;
- 想微调“开头更轻盈”,把第一个 y(y1)调小到 0.05~0.2,别低于 0
- 想让“结尾有弹性”,第二个 y(y2)可设为 1.2~1.5,但 x2 别超过 0.9,否则回弹延迟太长
- 调试时直接用 Chrome DevTools 的动画面板点开
animation-timing-function编辑器,拖动控制点比手敲数字靠谱得多
animation-timing-function 对性能和兼容性的影响
这个属性本身不触发重排(reflow),只影响重绘(repaint)节奏,所以只要动画属性本身是合成层友好型(如 transform、opacity),换任何 animation-timing-function 都不会掉帧。
真正影响体验的是人眼对加速度变化的敏感度:比如用 cubic-bezier(0.4, 0, 0.2, 1)(标准的“缓动”)做 300ms 的位移,比 ease-in-out 更顺;但换成 cubic-bezier(0.68, -0.55, 0.27, 1.55)(Material Design 推荐的“快速启动+柔和收尾”),在低端安卓机上可能因插值计算稍多而偶现卡顿——不是渲染问题,是浏览器 JS 主线程插值调度的小抖动。
- 老版本 iOS Safari(cubic-bezier() 中 y 超出 [0,1] 的写法,会直接 fallback 到
ease - 如果用 Web Animations API 动态设置 timing function,传入非法值(如 x1=-0.1)会导致整个 animation 失效,控制台报
InvalidStateError
多个关键帧里 timing-function 能不能分段控制
可以,但必须用 @keyframes 内的 animation-timing-function,而不是元素上的那个全局值。元素级的 animation-timing-function 只作用于整个动画周期,无法分段。
例如你想让 0%→50% 加速,50%→100% 减速,就得写:
@keyframes slide-fade {
0% { opacity: 0; transform: translateY(20px); }
50% {
opacity: 1;
transform: translateY(0);
animation-timing-function: ease-in;
}
100% {
opacity: 1;
transform: translateY(0);
animation-timing-function: ease-out;
}
}
注意:animation-timing-function 在 keyframe 里只对“当前帧到下一帧”的区间生效,且必须写在该帧声明块内;漏掉 50% 或 100% 的声明,中间那段就会继承前一段的曲线,不是默认 ease。
这种写法在复杂交互动画中很实用,但也容易被忽略一个细节:浏览器对 keyframe 内 timing-function 的解析是“向前覆盖”,也就是说,如果你在 30% 帧写了 animation-timing-function: linear,它会影响 30%→下一个有声明的帧(比如 50%)之间的过渡,而不是 30%→100% 全程。










