抖动动画应使用 translatex() 实现左右位移,而非 rotate();需配合 @keyframes 定义 0%/25%/50%/75%/100% 偏移序列,偏移量控制在 ±2px~±6px;必加 animation-fill-mode: forwards(或用 both),缓动选 cubic-bezier(.36,.07,.19,.97);js 触发前需清空旧动画并强制重排;移动端慎用 will-change,仅加 translatez(0) 保障硬件加速。

抖动动画用 @keyframes 实现,别直接改 transform: rotate()
抖动不是旋转,是左右位移的快速往复。用 rotate() 做抖动会歪斜、失真,还容易触发重排。正确做法是只动 translateX(),配合 @keyframes 定义 0% → 25% → 50% → 75% → 100% 的偏移序列。
- 典型错误:写成
@keyframes shake { from { transform: rotate(-5deg); } to { transform: rotate(5deg); } }—— 这是晃头,不是抖提示 - 推荐写法:
@keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 50% { transform: translateX(4px); } 75% { transform: translateX(-4px); } } - 偏移量建议控制在 ±2px ~ ±6px;超过 8px 在小屏上容易误触或视觉不适
触发抖动要用 animation,但别漏掉 animation-fill-mode: forwards
抖完要停在初始位置,否则元素可能卡在最后偏移态,影响后续交互。不加 animation-fill-mode,动画一结束就回跳,看起来像“抖一下又弹回去”,用户感知差。
- 必加参数:
animation: shake 0.4s cubic-bezier(.36,.07,.19,.97) both;(both=forwards+backwards) - 缓动函数选
cubic-bezier(.36,.07,.19,.97)比ease-in-out更干脆,避免拖尾感 - 别用
infinite——提示抖动是瞬时反馈,不是循环特效
JS 触发抖动前先清旧动画,否则连续点击会堆叠卡顿
用户连点两次提交按钮,如果没手动清除上一次的 animation,CSS 动画会叠加执行,DOM 渲染压力变大,甚至出现“越抖越慢”或“抖不动”的现象。
- 触发前加一句:
element.style.animation = 'none';(强制清空当前动画) - 再用
void element.offsetWidth;强制重排,确保清空生效 - 最后赋新动画:
element.style.animation = 'shake 0.4s ...'; - 不推荐用
classList.toggle()切换 class——class 未移除时重复添加无效
移动端要注意 transform 硬件加速和 Safari 兼容性
iOS Safari 对 translateZ(0) 或 will-change: transform 敏感,加了可能让抖动变卡,不加又可能触发软件渲染导致掉帧。
- 稳妥方案:只对抖动元素加
transform: translateZ(0);,不加will-change - Safari 15.4+ 支持
animation-composition: replace,但目前无需主动启用 - 真机测试重点看输入框失焦后抖动是否延迟——iOS 上
:focus+animation组合有时有 100ms+ 延迟
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











