用@keyframes做跳动更可靠,因其能定义多帧节奏(如下压→上顶→回弹)、配合cubic-bezier实现弹性缓动,并支持animation-fill-mode:forwards锁定终态;直接:hover写transform只能匀速位移,无法模拟物理跳动。

为什么用 @keyframes 做跳动比直接写 transform: translateY() 更可靠
直接在 :hover 里写 transform: translateY(-5px) 只能实现“抬升”,不是“跳动”——跳动需要位移 + 加速 + 回弹的节奏感。CSS 动画必须靠 @keyframes 定义关键帧,再配合 animation 触发,否则浏览器无法计算缓动曲线和循环行为。
常见错误是把动画写成线性位移:0% { transform: translateY(0); } 100% { transform: translateY(-10px); },结果看起来像匀速上浮,毫无弹性。真正跳动要模拟物理回弹,至少得三帧:下压 → 上顶 → 微回弹。
-
@keyframes必须定义在全局作用域(不能嵌套在类或媒体查询内),否则部分浏览器(如旧版 Safari)会忽略 - 动画名建议用语义化命名,比如
jump-bounce,避免和项目里其他jump动画冲突 - 别用
infinite除非真需要循环跳动;多数图标悬停只需一次完整跳跃,设animation-iteration-count: 1
怎么写一个有弹性的跳动 keyframe
核心是利用 cubic-bezier(.28,.84,.42,1) 模拟弹簧回弹,比 ease-out 更有“蹬地跃起”的感觉。关键帧顺序不能乱:先轻微下压(制造预备动作),再快速上顶,最后小幅回落停稳。
@keyframes jump-bounce {
0% {
transform: translateY(0);
}
20% {
transform: translateY(4px); /* 先微压,像蹲下 */
}
50% {
transform: translateY(-12px); /* 猛向上 */
}
70% {
transform: translateY(-6px); /* 回弹一半 */
}
100% {
transform: translateY(0); /* 落回原位 */
}
}
- 总时长建议控制在
0.4s ~ 0.6s,太短显得突兀,太长失去“跳”的即时感 - 位移量按图标尺寸调整:16px 图标用 ±12px 合理,24px 图标可放大到 ±16px
- 如果跳动后图标边缘出现模糊,加
will-change: transform;到悬停元素上,强制 GPU 加速
如何绑定动画到图标并防止重复触发
直接写 .icon:hover { animation: jump-bounce 0.5s; } 会导致鼠标反复进出时动画中断重播,产生卡顿或错帧。必须用 animation-fill-mode: forwards 锁定结束状态,并配合 animation-play-state 控制启停。
.icon {
display: inline-block;
transition: transform 0.2s;
}
.icon:hover {
animation: jump-bounce 0.5s cubic-bezier(.28,.84,.42,1) forwards;
}
/* 防止快速移入移出重复播放 */
.icon:not(:hover) {
animation-play-state: paused;
}
- 必须加
forwards,否则动画一结束就跳回translateY(0),失去“停在最高点再落回”的过程感 - 不要给
.icon自身设transform(比如居中用的translate),否则会和动画里的translateY冲突叠加 - 如果图标是 SVG,确保其父容器没设
overflow: hidden,否则上跳时可能被裁切
移动端悬停失效怎么办
手机端没有 :hover,但用户点击图标时仍需反馈。不能只依赖伪类,得用 JavaScript 补充触发逻辑,且避免引入额外事件监听开销。
- 最轻量方案:给图标加
ontouchstart=""属性(空字符串即可),iOS Safari 会为该元素启用 hover 模拟 - 更稳妥做法:监听
click事件,动态添加临时 class:icon.classList.add('jump-trigger');,并在 CSS 中写.icon.jump-trigger { animation: jump-bounce ... } - 注意清除时机:用
setTimeout(() => icon.classList.remove('jump-trigger'), 600),时间略长于动画时长,避免连续点击堆积 - 别用
pointer-events: none或禁用缩放等操作来“优化”,这会破坏可访问性
跳动动画真正难的不是写对 keyframe,而是让每一次触发都干净、不打架、不抢资源。特别是图标密集的导航栏,几十个同时 hover,transform 和 will-change 的组合稍不注意就会引发重排或掉帧。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











