用单个@keyframes配合分段cubic-bezier缓动模拟重力下落与三次衰减弹跳,手动设置translatey像素值、触底压缩scaley及偏转rotate提升真实感。

用 transform + animation 模拟重力下落,但别真写牛顿公式
纯 CSS 做不出真实物理引擎,但能靠关键帧和缓动函数骗过眼睛。核心是用 cubic-bezier() 拟合加速下落 + 弹跳衰减——不是靠多段动画拼接,而是单个 @keyframes 里控制速度曲线。
- 下落阶段用
cubic-bezier(0.2, 0.7, 0.4, 1)(先慢后快,模拟重力加速度) - 触底反弹用
cubic-bezier(0.1, 0.9, 0.2, 1)(快速回弹但幅度递减) - 别用
ease-in-out:它对称,而真实反弹是不对称的——下落快、回弹慢且短
animation-timing-function 必须分段写,不能只设一个全局值
一个动画里不同阶段需要不同缓动,CSS 不支持单 keyframe 内切缓动,所以得把整个过程拆成多个 animation 层叠,或用 @keyframes 手动定义每段的速度变化点。
- 推荐方案:单个
@keyframes,在0%→60%用下落缓动,60%→85%用第一次反弹,85%→100%用二次微弹 - 错误写法:
animation: fall 1.2s ease-in;—— 这只会匀速加速,没反弹感 - 注意
animation-fill-mode: forwards,否则动画结束会跳回初始位置
反弹高度要逐次衰减,用 transform: translateY() 硬调数值
视觉上“弹三次”不等于时间上均分,而是位移幅度按约 60%→30%→10% 衰减。别指望 CSS 自动算衰减,得手动写死每段的 translateY 值。
- 假设容器高 400px,下落终点是
translateY(380px)(留 20px 视觉缓冲) - 第一次反弹到
translateY(280px)(≈ 70% 高度),第二次到translateY(340px)(小幅回弹),第三次到translateY(370px) - 别用百分比单位做反弹:父容器尺寸变化时,反弹比例会错乱,固定像素更可控
真实感陷阱:忽略惯性延迟和旋转晃动,动画就假
刚体落地瞬间会有微小压缩+回弹,以及轻微偏转。纯垂直位移看着像PPT,加一点 scaleY(0.95) 和 rotate(1deg) 能立刻提升可信度。
立即学习“前端免费学习笔记(深入)”;
- 在触底帧(比如
60%)加transform: translateY(380px) scaleY(0.95) rotate(-1deg); - 反弹起始帧(
61%)立刻恢复scaleY(1) rotate(0),制造“弹起来”的干脆感 - 慎用
will-change: transform:低端安卓机上可能引发闪烁,只在必要时加










