真正弹跳需分段贝塞尔曲线模拟物理过程:0%→25%快进慢出下落,25%→50%快出慢进触底回弹,50%→75%小幅二次反弹,75%→100%回稳,配合forwards填充和will-change优化性能。
transform: translateY() 做不出弹跳感单纯线性位移(比如从 0 到 -20px 再回 0)看着像上下晃,不是弹跳。真实弹跳有加速度变化:下落快、触底挤压、回弹衰减。CSS 的 @keyframes 本身不支持物理模拟,得靠贝塞尔曲线拟合“弹性”节奏。
ease-in-out 太匀速,像钟摆,不像弹簧c
ubic-bezier(0.28, 0.84, 0.6, 1) 这类高弹性值——这是模仿 Material Design 的弹跳缓动@keyframes bounce
下面这段是经过实测的「一次完整弹跳」动画,包含 4 个关键帧,用 cubic-bezier 控制每段节奏:
@keyframes bounce {
0% {
transform: translateY(0);
}
25% {
transform: translateY(-30px);
animation-timing-function: cubic-bezier(0.28, 0.84, 0.4, 1);
}
50% {
transform: translateY(0);
animation-timing-function: cubic-bezier(0.72, 0, 0.96, 0.28);
}
75% {
transform: translateY(-10px);
animation-timing-function: cubic-bezier(0.72, 0, 0.96, 0.28);
}
100% {
transform: translateY(0);
}
}
25% 是下落峰值,位移最大,用「快进慢出」让下落加速、触底前减速(模拟重力+缓冲)50% 回到原位但立刻接小幅二次上抬(75%),制造弹簧余震感animation-timing-function,它只作用于当前关键帧到下一帧的过渡关键在动画触发时机和复用控制:用 animation 简写属性绑定,并禁用鼠标悬停等干扰行为。
icon--bounce-on-load
animation: bounce 0.8s ease-out forwards;
forwards 防止动画结束后图标跳回初始位置animation-delay: 0.2s 可错开多个图标入场,避免同时抖动animation-iteration-count: infinite,否则会一直弹——除非你真想要魔性效果示例样式:
.icon--bounce-on-load {
display: inline-block;
animation: bounce 0.8s cubic-bezier(0.28, 0.84, 0.6, 1) forwards;
}
移动端 Safari 和旧版 Android WebView 对 transform + keyframes 组合有渲染毛刺,尤其在低配设备上。
will-change: transform 提前告知浏览器该元素将动画,触发 GPU 加速top/left 和 transform 动画——会强制重排,卡顿明显cubic-bezier() 在 @keyframes 内使用,如果还要兼容,得降级为 ease-out 并缩短动画时长(0.5s)inline 或 inline-block,否则 transform 可能失效(block 元素需明确宽高或触发 BFC)最终上线前,在真机上快速滚动页面,看图标是否偶发闪烁或位移偏移——那是硬件加速未生效的信号。