cubic-bezier() 不跳变的关键是四个参数必须严格在 [0, 1] 范围内,且 y₁ ∈ [0.05, 0.3]、y₂ ∈ [0.7, 0.95] 以保证起止斜率连续;越界会导致浏览器自动修正或行为不一致。

css cubic-bezier() 怎么写才不跳变
贝塞尔曲线跳变,八成是控制点越界了。cubic-bezier() 四个参数必须全在 0–1 范围内,超出就触发浏览器“自动修正”——比如 Chrome 会把 cubic-bezier(0, 2, 1, -1) 强行掰成 cubic-bezier(0, 1, 1, 0),结果就是瞬间完成过渡,看着像没动。
真正可控的写法只有一条:四个数都老老实实卡在 [0, 1] 里。想拉出缓入缓出?用 cubic-bezier(0.25, 0.1, 0.25, 1);要先慢后快再慢?cubic-bezier(0.42, 0, 0.58, 1) 更稳。
- 别信“负值能做出更夸张效果”的说法——CSS 规范明确要求参数 ∈ [0,1],越界行为未定义,不同浏览器处理方式不同
-
ease、ease-in-out等预设本质就是固定参数的cubic-bezier(),比如ease=cubic-bezier(0.25, 0.1, 0.25, 1) - 调试时直接用浏览器开发者工具的动画面板拖动控制点,它会实时生成合法参数,比手算靠谱
用 cubic-bezier() 模拟真实物理动效的关键约束
真实运动有加速度连续性,对应到贝塞尔曲线,就是起始和结束斜率不能为零或无穷(即导数不能为 0 或 ∞)。否则会卡顿或突兀收尾。
起始斜率由第二个参数决定:y₁ 越小,初速度越快;y₂ 越大,末速度越快。但 y₁=0 或 y₂=1 会让起点/终点切线水平,导致“顿挫感”。
立即学习“前端免费学习笔记(深入)”;
- 安全区间建议:y₁ ∈ [0.05, 0.3],y₂ ∈ [0.7, 0.95],比如
cubic-bezier(0.3, 0.08, 0.7, 0.92) - 避免
cubic-bezier(0.5, 0, 0.5, 1):虽然合法,但 y₁=0 导致起步僵硬,y₂=1 导致收尾生硬 - 移动端尤其敏感,iOS Safari 对斜率突变更明显,同一段曲线在桌面端顺滑,手机上可能“咯噔”一下
transition-timing-function 和 animation-timing-function 用法差异
两者都支持 cubic-bezier(),但作用对象和覆盖逻辑不同,混用容易失效。
transition-timing-function 只管单次属性变化,比如 hover 时 opacity 变化;而 animation-timing-function 是动画关键帧之间的插值规则,写在 @keyframes 外部,对整个动画生效。
- 如果同时写了
transition: all 0.3s和@keyframes slide { from { left: 0; } to { left: 100px; } },那left动画走的是@keyframes里的 timing function(默认ease),跟 transition 无关 - 想让 transition 也用自定义曲线,必须显式写:
transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1) - 注意优先级:内联 style > CSS 文件中靠后的规则 > 靠前的规则,
!important在 timing function 上无效
哪些场景不适合硬套 cubic-bezier()
不是所有动效都适合手动调贝塞尔。有些需求用其他方式更稳、更轻量。
比如需要逐帧控制节奏(如呼吸灯、打字机)、或依赖滚动位置/鼠标坐标实时计算的过渡,cubic-bezier() 的静态四参数根本不够用,强行塞只会让逻辑越来越绕。
- 滚动驱动动画:用
scroll-timeline+animation-timeline(Chrome 115+)或 JS 监听scroll事件 +requestAnimationFrame - 鼠标跟随类效果:用
transform: translate()+ JS 实时更新,比任何 CSS 缓动都跟手 - 复杂路径位移(如抛物线、环形):CSS
offset-path+offset-rotate比拼凑多个cubic-bezier()更直观
贝塞尔曲线是工具,不是解药。参数调得再细,也盖不住动效逻辑本身是否合理。真正难的从来不是怎么写 cubic-bezier(),而是判断该不该在这里用它。










