应使用 transition: transform 0.25s–0.35s cubic-bezier(0.34,1.56,0.64,1),配合 translateX()/translateY() 实现高性能平滑移动;避免 left/top 触发重排,禁用 transition: all。

直接给 transition 但只作用于位置属性
想让元素移动(比如 left、top、transform)时平滑过渡,不能只写 transition: all 0.3s ease —— 这会把所有属性都过渡,可能引发意外动画(比如文字颜色、边框粗细也跟着动)。应该明确限定只对位置相关属性生效。
-
transform是首选:用translateX()/translateY()移动,配合transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) - 避免用
left/top配合position: relative/absolute:它们触发重排(layout),性能差,且无法硬件加速 - 如果必须用
left,至少写成transition: left 0.3s ease-out,不带all
transform + transition 的典型写法
这是目前最可靠、性能最好的移动过渡方案。关键点在于:位移必须通过 transform 改变,且该属性本身要参与 transition 声明。
button {
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
button:hover {
transform: translateX(8px);
}
- 缓动函数推荐
cubic-bezier(0.34, 1.56, 0.64, 1)(轻微 overshoot,比默认ease更有动感) - 时间建议在
0.2s–0.35s之间:太短显得突兀,超过0.4s用户会觉得响应慢 - 不要在父容器上设
will-change: transform除非真有卡顿——现代浏览器通常自动优化
为什么 left 和 transform 的过渡效果不同
根本区别不在“能不能动”,而在浏览器渲染流水线中的处理阶段:left 触发 layout → paint → composite;transform 跳过前两步,只走 composite,所以更顺、更省电。
- 用
left移动时打开 Chrome DevTools → Rendering → 勾选 “Paint flashing”,能看到大片绿色闪烁(说明频繁重绘) - 用
transform则几乎不闪,且在低端设备上也不易掉帧 - 若元素已有
transform: rotate(5deg),又想加平移,别写两个transform,合并为transform: rotate(5deg) translateX(10px)
过渡失效的三个常见原因
写了 transition 却没动画?大概率掉进这几个坑里。
立即学习“前端免费学习笔记(深入)”;
- 起始状态和结束状态的值类型不匹配:比如从
transform: none→transform: translateX(10px)没问题;但从transform: scale(1)→translateX(10px)就会中断动画(因为none和scale()不同构) - 过渡属性名拼错:
transfrom、transtion、trasnform都不会生效 - 元素没有触发重绘/重排:比如用 JS 直接改
style.left但没触发 layout,或用了will-change: transform却忘了初始transform: translateZ(0)占位
transform 动画没问题;但滚动锚点跳转时强行加位移过渡,反而干扰用户预期。动,得有理由。










