纯CSS弹跳动画需缩放与位移组合并用cubic-bezier模拟回弹,因真实弹跳含下落、压缩、回弹、震荡多阶段,单用scale丢失垂直动量感;关键帧须包含7个精准时点以实现可信物理效果,并注意transform-origin、animation-fill-mode和overflow配置。

直接用 @keyframes 定义缩放 + 位移组合动画,配合 cubic-bezier() 模拟物理回弹,比单独用 scale() 或单独用 translateY() 更真实。纯 CSS 就能搞定,不需要 JS。
为什么不能只用 scale() 做弹跳
弹跳不是简单放大缩小——它包含下落、触底压缩、回弹、小幅震荡几个阶段。只改 scale() 会丢失垂直动量感,看起来像“气球被按扁又松开”,而不是“球砸地后弹起”。真实弹跳必然伴随 translateY() 的位移变化,且各阶段速率非线性。
-
scale(1.2)在触底时制造“压缩感”,但必须同步translateY(5px)模拟形变下沉 - 回弹阶段要先快后慢,
cubic-bezier(0.28, 0.84, 0.42, 1)比ease-out更接近重力衰减 - 最后 1–2 次微震需用
scale(0.98) → scale(1)和translateY(-2px) → translateY(0)配合,否则停得太硬
@keyframes bounce-scale 的关键帧怎么写
下面这个 7 步关键帧是经过实测的最小有效结构,兼顾视觉可信度和性能(避免过多中间帧):
@keyframes bounce-scale {
0% { transform: translateY(-30px) scale(0.9); }
30% { transform: translateY(0) scale(1.15); }
45% { transform: translateY(-8px) scale(0.95); }
60% { transform: translateY(0) scale(1.03); }
75% { transform: translateY(-3px) scale(0.98); }
90% { transform: translateY(0) scale(1.01); }
100% { transform: translateY(0) scale(1); }
}
- 起始
translateY(-30px)模拟预跳高度,scale(0.9)提前暗示压缩趋势 - 30% 是触底峰值:
scale(1.15)+ 到达translateY(0),形成最大形变 - 45% 和 75% 的负向位移是回弹过冲,没有它就没有“弹”感
- 结尾两帧必须回到
scale(1)和translateY(0),否则animation-fill-mode: forwards会卡在错误状态
应用动画时最容易漏掉的三个配置
写完关键帧却没效果?大概率栽在这三处:
立即学习“前端免费学习笔记(深入)”;
- 没设
transform-origin: center:默认原点在左上角,缩放+位移一叠加,元素就往右下“滑出去”了 - 忘了加
animation-fill-mode: forwards:动画播完立刻跳回初始态,根本看不到“落地静止”的最终帧 -
overflow: hidden父容器裁剪了位移:弹跳过程元素会短暂超出原始尺寸,父级若设了overflow: hidden,就会被截断——临时改成visible测试,或扩大父容器 padding
真正难的是让多次弹跳自然衰减,CSS 本身不支持动态调整关键帧数值,所以超过 2 次明显回弹就得切到 JS 控制节奏,或者用 Web Animations API 手动插值。纯 CSS 方案里,把第 3 次以后的震荡幅度压到 ±0.01,人眼基本就接受为“停稳”了。



















