用 transform 实现抖动效果性能更好,因不触发重排;margin/left/right 会引发重排导致卡顿;需配合 will-change: transform 和 overflow: hidden 避免溢出;@keyframes 要起止归零、混合位移旋转、节奏紧凑;单次触发需设 animation-iteration-count: 1 并监听 animationend 移除类;移动端需临时禁用 pointer-events、touch-action 和焦点。直接用 CSS 的
@keyframes + transform: translate() + rotate() 就能做出真实感强、性能好的抖动效果,不需要 JS,也不推荐用 margin 或 left/right。这类属性会触发浏览器重排(reflow),动画一卡一卡,尤其在低端设备或复杂页面里明显掉帧。抖动本该是“快而脆”的反馈,卡顿反而削弱警示效果。
transform 只影响合成层,GPU 加速,不触发布局计算will-change: transform(可选但推荐)提前提示渲染器overflow: hidden,抖动时元素可能短暂移出边界,视觉上“漏出来”核心是位移和旋转的组合,数值要小(±1px~±3px,±0.5deg~±1.5deg),节奏要紧凑(0.4s~0.6s),关键帧别少于 8 个,否则容易显得机械。
@keyframes shake { 0% { transform: translate(0, 0) rotate(0); } 10% { transform: translate(-2px, -1px) rotate(-0.8deg); } 20% { transform: translate(1px, 2px) rotate(1.2deg); } 30% { transform: translate(-2px, 0) rotate(-0.5deg); } 40% { transform: translate(2px, -1px) rotate(0.7deg); } 50% { transform: translate(-1px, 1px) rotate(-1deg); } 60% { transform: translate(2px, 0) rotate(0.3deg); } 70% { transform: translate(-1px, -2px) rotate(-0.6deg); } 80% { transform: translate(1px, 1px) rotate(0.9deg); } 90% { transform: translate(-2px, 0) rotate(-0.4deg); } 100% { transform: translate(0, 0) rotate(0); }}
translate(0, 0) rotate(0),否则动画循环时有跳变多数场景(比如表单校验失败)只需要抖一次,而不是一直晃。靠 animation-iteration-count 和 JS 配合最稳。
animation: shake 0.5s ease-in-out 1;(末尾 1 表示只播一次)animationend 事件自动移除,防止样式残留:element.addEventListener('animationend', () => element.classList.remove('shake'));
animation-iteration-count: infinite 然后靠 JS 中途停——浏览器不保证能精确中断,可能卡在中间帧iOS Safari 和新版安卓 Chrome 对可交互区域有默认行为干预。如果抖动的是按钮或输入框,用户可能在抖动过程中误点,或手指划过时触发页面滚动而非等待抖动结束。
立即学习“前端免费学习笔记(深入)”;
pointer-events: none,动画结束再恢复touch-action: none 防止手势冲突<input> 类元素,抖动中临时设 tabindex="-1" 并 blur() 当前焦点,避免键盘弹出干扰