纯css无法实现真实物理重力,但可通过分段keyframes、逐级衰减的cubic-bezier缓动、transform位移与形变模拟可信弹跳效果。

纯 CSS 无法模拟真实物理重力(比如加速度、碰撞能量衰减、实时速度积分),但可以用 animation + 关键帧 + 缓动函数逼近视觉上“像重力作用”的弹跳效果——关键不在物理精度,而在人眼感知的可信度。
用 cubic-bezier() 模拟下落加速和触地反弹
CSS 动画本身是时间线性插值,要“看起来加速下落”,就得用非线性缓动。标准弹跳常用 cubic-bezier(0.2, 0.6, 0.4, 1) 模拟初段加速;反弹阶段则需更陡的出点(如 cubic-bezier(0.05, 0.75, 0.2, 1))来表现压缩-回弹感。
实际做法:
- 把整个动画拆成多个
@keyframes片段:下落 → 触地压缩 → 第一次反弹 → 衰减反弹(2–3次) - 每段用不同
cubic-bezier(),且后一段的持续时间应逐次缩短(如 400ms → 300ms → 200ms) - 触地瞬间加
transform: scaleY(0.8)模拟形变,紧接着恢复
避免用 steps() 或 linear 破坏物理感
常见错误是全程用 linear 或简单 ease-in-out,结果像匀速掉盒子。更糟的是误用 steps(1, end) 做“顿挫”——那只是卡帧,不是弹跳。
真正需要控制的是:
- 下落阶段必须有明显加速感:起始位移慢,中后段快 → 选
cubic-bezier(0.2, 0.2, 0.4, 1)类型 - 反弹最高点必须有“悬停感”:在顶点附近多停留几帧(通过 keyframe 百分比拉长该区间)
- 所有反弹高度应递减:第 2 次反弹 y 位移设为原高的 60%,第 3 次设为 30%
用 transform: translateY() 而非 top 保证性能
直接改 top 会触发 layout + paint,掉帧明显;transform: translateY() 由合成器处理,60fps 更稳。
同时注意:
- 元素需开启硬件加速:
will-change: transform或transform: translateZ(0) - 不要对
height或margin做动画——它们必然触发重排 - 如果容器有
overflow: hidden,确保弹跳范围不被意外裁剪
真正的难点不在写几段 keyframe,而在于调参:每次反弹的时长比例、y 位移衰减系数、压缩形变幅度,三者必须协同。差 5% 就显得“轻飘”或“死沉”。建议先用 DevTools 的 animation 面板拖动时间轴,逐帧看节奏是否自然。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











