用 transform: translatex() 实现 shake 动画,幅度 ±5px–±12px,4–5 帧关键帧,加 animation-fill-mode: forwards;响应式用 vw 控制幅度,禁用 left/margin;排查 display/visibility/overflow 干扰;移动端加 pointer-events: none 和 prefers-reduced-motion 降级。

用 @keyframes shake 实现左右摇摆,别碰 left 和 margin
直接改 left 或 margin-left 会强制浏览器重排(reflow),动画卡顿、掉帧、边缘发虚。必须用 transform: translateX()——它走合成器线程,60fps 有保障。
- 位移量控制在
±5px到±12px之间:太小不明显,太大像故障 - 关键帧建议分 4–5 帧(如 0% → 25% → 50% → 75% → 100%),避免只写两帧导致生硬弹跳
- 必须加
animation-fill-mode: forwards,否则动画结束瞬间元素会“啪”地弹回原位 - 如果父容器是 Flex 或 Grid,检查子元素是否被
align-self: center拉偏——临时改成flex-start排查
响应式适配的关键不是媒体查询,而是单位选择
很多人一想到“响应式”就写一堆 @media,其实更轻量的解法是换单位:用 vw 替代 px 控制晃动幅度,让抖动强度随屏幕宽度自然缩放。
- 比如把
translateX(-8px)改成translateX(-1.2vw),小屏抖得轻,大屏更有存在感 - 动画时长保持相对固定(
0.5s–0.6s),别用vw或%改时长,否则小屏快得看不清,大屏慢得像卡顿 - 慎用
em/rem:如果图片父级字体大小被重设过,translateX(1em)可能意外放大抖动
为什么加了动画但图片没晃?三类高频拦截点
90% 的“没反应”问题不出在 keyframes 本身,而是被其他样式静默屏蔽了。
- 检查开发者工具里该元素的 computed 样式,确认
animation属性是否真实生效(注意大小写:shake≠Shake) -
display: none、visibility: hidden、或父级overflow: hidden裁剪区域太小,都会让动画不可见 - 如果用了
will-change: transform,必须在动画触发前就加上;旧版 Safari 会跳过首帧,导致“第一下不晃” - 某些 CSS 重置库(如 normalize.css)可能设了
animation: none全局覆盖,需显式重写
移动端防误触和性能兜底
用户真去晃手机时,你写的“摇摆动画”反而会干扰交互体验,尤其表单校验失败后自动触发的 shake,容易和陀螺仪冲突。
- 给触发 shake 的元素加
pointer-events: none(动画期间禁交互),结束后再恢复 - 用
@media (prefers-reduced-motion: reduce)主动降级:把animation改成none或退化为简单边框高亮 - 别在
:hover上直接写完整 shake 动画——PC 端没问题,但触摸屏长按会误触发,改用:active+ 短暂脉冲更安全
transform 偏移状态(哪怕归零),若后续 JS 读取 getBoundingClientRect() 或做碰撞检测,坐标值已失真。需要明确知道——transform 不改变文档流位置,但会改变视觉坐标系。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











