图标震动应使用@keyframes配合transform: translateX()实现1–2px位移,频率0.4s、timing-function设为linear,hover时用animation-play-state控制启停,避免与transition冲突,慎用于移动端及信息类图标。

用 @keyframes 做图标震动,位移量必须控制在 1–2px
震动效果本质是快速左右/上下偏移,人眼感知为“抖”,但位移太大就变晃动甚至跳脱。CSS 动画里用 transform: translateX() 最稳妥,避免触发重排。
常见错误是直接用 margin 或 left,导致布局抖动、文字错位,甚至影响父容器高度。
- 推荐写法:
@keyframes shake { 0% { transform: translateX(0); } 25% { transform: translateX(-1px); } 50% { transform: translateX(1px); } 75% { transform: translateX(-1px); } 100% { transform: translateX(0); } } - 震动频率建议设为
0.4s左右(太快看不清,太慢像卡顿),animation-timing-function: linear更干脆 - 别用
infinite—— 悬停中反复震动会干扰用户操作;加animation-fill-mode: forwards也不必要,悬停结束就该归位
:hover 触发震动时,要防连续触发和过渡冲突
鼠标快速进出图标区域,容易堆积动画帧,造成卡顿或残留抖动。这不是浏览器 bug,而是 CSS 动画未被及时中断的表现。
- 必须加
animation-play-state: paused初始状态,再在:hover里设为running,否则移入瞬间可能跳过第一帧 - 如果图标本身有
transition(比如颜色渐变),震动动画会和它抢transform,结果震动失效或延迟 —— 解决办法是把所有transition属性显式写成transition: color 0.2s, background 0.2s,排除transform - 移动端慎用:部分 iOS Safari 在
:hover上行为不一致,建议用touchstart+ JS 切换 class 替代纯 CSS 方案
图标元素必须是 inline 或 inline-block,且有明确尺寸
震动依赖 transform,而 transform 对 display: inline 元素默认无效(除非加 vertical-align 或改 display)。很多 SVG 图标或字体图标(如 Font Awesome)默认是 inline,但没设宽高,translate 就会“飘”。
- 给图标加
display: inline-block是最简解法 - SVG 图标建议加
width和height(哪怕只是1em),否则震动时基线可能浮动,牵连周围文字 - 用伪元素(
::before)挂图标时,务必设content: ""+display: inline-block,否则transform不生效
震动不是万能反馈,得看场景和图标类型
震动适合强调操作可交互性(比如删除按钮、开关控件),但对信息类图标(如“帮助”“设置”)反而降低可信度。更隐蔽的问题是:震动会放大抗锯齿差异,某些字体图标在小尺寸下边缘发虚,一抖更明显。
立即学习“前端免费学习笔记(深入)”;
- 深色背景上慎用高频震动 —— 易引发视觉疲劳,尤其对光敏用户
- 图标含描边或阴影时,震动会让边缘“闪烁”,建议动画中关闭
filter或box-shadow - 真正需要强反馈的场景(如误操作确认),震动应配合颜色变化(如红闪)或轻微缩放,单靠位移力度不够
震动幅度、节奏、触发时机这三处稍一松动,效果就从“灵巧”滑向“廉价”。调的时候盯着真机看两秒,比写十行代码还管用。


















