震动必须用 transform: translateX() 和 @keyframes 实现,禁用 margin/left;需控制时长 0.4s、位移±8px 内、避免动画叠加,并针对低版本浏览器降级处理。

震动效果必须用 transform: translateX(),不能用 margin 或 left
因为只有 transform 和 opacity 是能被浏览器直接交由合成线程处理的属性,用 margin 或定位会触发 layout + paint,震动一卡一顿,甚至在低端机上直接掉帧。震动本质是高频小位移,对性能敏感。
实操建议:
- 震动动画必须定义在 class 上(比如
.shake),通过 JS 切换 class 控制触发,别用style.transform写内联样式——否则无法复用 CSS 动画、也难控制重播 - 动画时长控制在
0.4s以内,太长像晃手机,太短()人眼感知不到 - 推荐用
@keyframes shake定义 5–7 帧位移,避免用ease-in-out这类缓动——它会让中间段速度变慢,削弱“顿挫感”
transition 对震动无效,必须用 @keyframes + animation
transition 只能在两个状态间平滑插值,比如从 translateX(0) 到 translateX(10px);但震动需要来回多次偏移(0 → 8 → −6 → 4 → 0),这超出了 transition 的能力范围。
常见错误现象:写了 transition: transform 0.3s,再 JS 改 transform,结果只动了一次,没震动。
立即学习“前端免费学习笔记(深入)”;
正确写法示例:
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(6px); }
50% { transform: translateX(-4px); }
75% { transform: translateX(2px); }
100% { transform: translateX(0); }
}
.shake {
animation: shake 0.4s cubic-bezier(.36,.07,.19,.97);
}
注意:cubic-bezier(.36,.07,.19,.97) 是个“快起快落”曲线,比默认 ease 更有冲击力,且避免结尾拖尾。
表单验证失败时加震动,要防连续触发和动画叠加
用户快速连点提交、或输入中实时校验,容易导致 .shake class 被反复添加,而 animation 没结束就重播,造成卡顿或位移错乱。
使用场景:登录表单的 <input type="email"> 失焦校验、按钮点击后整体校验。
实操建议:
- 加完
.shake后立刻用setTimeout移除,时长略长于动画时长(如动画0.4s,则setTimeout设为450ms) - 加 class 前先检查元素是否已有
.shake,有就跳过——避免重复绑定动画 - 不要对整个
<form></form>加震动,只作用于出错的<input>或其父容器(比如<div class="field">),否则布局抖动影响其他字段 <h3>兼容性要点:IE 不支持 <code>@keyframes?其实可以降级IE10+ 支持
@keyframes,但需要-webkit-前缀(虽然 IE 不认这个前缀,但加了不报错);真正问题在 iOS Safari 9.3 以下不支持animation-fill-mode: forwards,导致震动完回不到原位。参数差异:
- 不用
animation-fill-mode,改用 JS 在动画结束时手动清 class(监听animationend事件) - Android UC 浏览器旧版本对
transform有渲染 bug,震动位移量别超过±8px,否则可能偏移出界 - 如果项目还要支持 IE9,震动就得放弃 CSS 方案,改用 JS 每 50ms 手动改
style.transform(不推荐,维护成本高)
- 不用


















