最稳妥的弹性动画起点是cubic-bezier(0.68,-0.55,0.27,1.55),因其y₁=-0.55实现反向蓄力、y₂=1.55确保过冲回弹,且x₁/x₂∈[0,1]、y₁/y₂∈[-0.5,2.0]保障兼容性与不降级。

纯 CSS 实现带回弹效果的弹性动画,核心不是堆砌关键帧,而是用 cubic-bezier() 控制时间与位移的非线性关系——只要 y₁ 1,就能触发浏览器原生的“超调→回弹”行为;但参数越激进,越容易在 Safari 或旧版 Chrome 中静默降级为 linear。
为什么 cubic-bezier(0.68, -0.55, 0.27, 1.55) 是最稳妥的起点
这组值在多数场景下能稳定出弹性感,且兼容 Chrome 43+/Firefox 16+/Safari 9+:
- y₁ = -0.55 让动画起始阶段“反向拉扯”,模拟弹簧被压缩的蓄力感
- y₂ = 1.55 使末段明显冲过目标位置再回落,形成一次自然过冲
- x₁ 和 x₂ 都落在 [0,1] 内,避免时间轴倒流导致卡顿(如
cubic-bezier(0.8, 0, 0.2, 1)就会跳变) - y₁/y₂ 均在 [-0.5, 2.0] 区间内,防止 Chrome 静默降级、Safari 截断为 1
验证是否生效:打开 Chrome DevTools → Animations 面板 → 点击 timing function 预览图,若显示为曲线而非直线,说明未降级。
必须用 transform,别碰 width、height 或 top/left
回弹动画若作用于布局属性,会强制触发布局重排(reflow),尤其在中低端 Android 或 iOS 上极易掉帧:
- ✅ 正确:对
transform: scale()、translateY()、scaleY()动画 - ❌ 错误:
transition: width 0.4s cubic-bezier(...)—— 曲线再准也卡 - ⚠️ 特别注意下拉菜单:不能用
height: auto,得改用max-height+overflow: hidden,并设合理上限(如max-height: calc(1.5em * 6 + 1.5rem))
侧边栏或弹窗类动画,还需加 will-change: transform(动画开始前注入,结束后立即移除),否则 iOS Safari 可能渲染撕裂。
拖动后回弹必须靠 JS 触发,CSS 无法监听 dragend
纯 CSS 没有事件监听能力,所谓“拖完自动回弹”,实际是 JS 捕获结束事件后动态加 class:
- JS 需先读取当前
getComputedStyle(el).transform,解析出实时位移值(如translateX(124px)) - 然后通过
el.style.transform = 'none'清除内联样式(否则 class 中的transform不生效) - 再添加带动画的 class,例如
.bounce-back,其@keyframes应匹配该位移量 - 动画必须带
animation-fill-mode: forwards,否则播完立刻跳回原始位置
示例关键帧(适配 translateX 场景):
@keyframes bounceBack {
0% { transform: translateX(124px); }
60% { transform: translateX(-16px); }
80% { transform: translateX(8px); }
100% { transform: translateX(0); }
}
注意中间关键帧(60%、80%)是手动设的反向偏移,比单靠 cubic-bezier() 更可控,也更像物理回弹。
多段弹跳要拆成多个 animation,别指望单次 @keyframes
真正像球落地反弹的效果,需要分段控制衰减节奏,单个缓动函数撑不起多次回弹:
- 第一段(主弹):快落 + 过冲 →
cubic-bezier(0.34, 1.56, 0.64, 1) - 第二段(衰减):小幅回弹 →
cubic-bezier(0.4, 0, 0.2, 1) - 第三段(微调):缓慢归位 →
cubic-bezier(0.2, 0, 0, 1) - 所有动画 duration 和 delay 必须严格递增,用逗号分隔:
animation: bounce 0.6s, bounce 0.6s 0.6s, bounce 0.6s 1.2s
另外,prefers-reduced-motion: reduce 下必须降级:直接禁用弹性,改用 ease 或 linear,否则会违反可访问性规范。
真正难的不是写出那串贝塞尔值,而是每次都要确认它在目标设备上没被降级、没触发 layout、没和 display: none 冲突、也没在用户开了减少动效时强行播放——这些细节不检查,弹性就变成了 bug。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











