抖动动画必须用 transform: translateX() 实现,配合 @keyframes shake 定义四状态关键帧,首尾为 0;校验失败时立即给错误元素添加 shake 类并监听 animationend 清理,避免样式覆盖、duration 为 0 或 overflow 隐藏等问题。

抖动动画该用什么 CSS 属性控制
抖动本质是水平位移的快速往复,必须用 transform: translateX() 实现,不能用 margin 或 left。前者触发 GPU 加速、无重排、性能可控;后两者会引发布局计算,连续抖动时容易卡顿甚至掉帧。
关键帧定义要覆盖「起始 → 右偏 → 左偏 → 回中」四个状态,且首尾必须都是 translateX(0),否则动画结束后元素会停留在偏移位置,影响下一次校验或用户操作。
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(4px); }
50% { transform: translateX(-4px); }
75% { transform: translateX(4px); }
100% { transform: translateX(0); }
}
怎么在表单校验失败时触发这个动画
不要监听 submit 后手动加 class——那会延迟反馈。应该在调用校验逻辑(比如 checkValidity() 或自定义验证函数)得到 false 结果的**同一时刻**,给对应表单项添加抖动类。
常见错误是直接对整个 form 元素加动画,实际应精准作用于出错的 input、select 或其包裹容器(如 .form-group),否则视觉干扰过大,且无法聚焦问题字段。
立即学习“前端免费学习笔记(深入)”;
- 使用
element.classList.add('shake')触发动画 - 动画结束后立刻用
element.addEventListener('animationend', () => element.classList.remove('shake'))清理 class,避免重复点击多次叠加 class 导致动画异常 - 若校验是异步的(如接口校验用户名是否已存在),需确保动画在拿到失败响应后再执行,不能在请求发出时就抖
为什么加了动画但没看到抖动
最常踩的坑是:CSS 动画被其他样式覆盖,或触发条件不满足。检查以下几点:
-
animation-name拼写错误,比如写成shak或大小写不一致(CSS 对动画名大小写敏感) - 缺少
animation-duration,默认为 0s,动画瞬间完成不可见 - 目标元素设置了
transform: scale(1)等其他 transform,会覆盖translateX,需合并写法:transform: scale(1) translateX(0) - 父容器有
overflow: hidden,而抖动位移超出容器边界,导致部分帧被裁剪——可临时加outline: 1px solid red边框辅助排查
要不要兼容老版本 Safari 或 iOS WebView
iOS 12.2+ 和 Safari 12.1+ 已原生支持 @keyframes 和 animation,无需前缀。但若项目仍需支持 iOS 10–11,得补 -webkit-keyframes 和 -webkit-animation。
不过要注意:Safari 旧版对 animation-timing-function 的解析更严格,避免用 cubic-bezier(.1,.9,.2,1.1) 这类超出 y 轴范围的值,否则整段动画可能失效。稳妥起见,用 ease-in-out 或省略该属性即可。
抖动幅度建议控制在 ±2px~±6px 之间,太大显得浮夸,太小用户感知不到;持续时间 0.4s~0.6s 最自然,再短像抽搐,再长像卡顿。


















