transition必须加在要动画的元素本身,而非触发器;需与变化属性精确匹配,避免all;初始态须明确;禁用top/left等布局属性;移动端需加translateZ(0)提升兼容性。

transition 要加在哪个元素上才生效
必须加在「要动的元素」本身,而不是它的父容器或触发元素。比如你 hover 一个按钮想让旁边的 .tooltip 滑入,transition 得写在 .tooltip 上,而不是按钮上。
常见错误是把 transition: transform 0.3s 写在触发器上,结果位移毫无动画——因为触发器自己没变 transform,真正要动的元素没声明过渡属性。
-
transition必须和将要变化的 CSS 属性配对:改transform就写transition: transform 0.3s;改opacity就得另加或合并写成transition: transform 0.3s, opacity 0.3s - 不要用
transition: all 0.3s,它会让所有可动画属性都响应变化,容易引发意外重绘(比如width或color突然也动起来) - 初始状态必须明确:如果元素一开始是
transform: translateX(0),那目标态就得是translateX(20px)这类具体值,不能依赖浏览器默认(比如从unset到translateX(20px)不会动画)
translate 动画卡顿?检查是否触发了重排
transform 本该走合成层、不触发重排,但一旦和某些属性混用就会掉回主线程渲染。最典型的是同时设置 top/left 和 transform,或者给元素加了 will-change: auto(等于没加)。
- 确保只用
transform控制位移,彻底弃用top、left、margin等布局属性做“移动” - 需要启用硬件加速时,加
will-change: transform,但仅限动画前一刻设置(比如 hover 时才加),避免长期占用 GPU 内存 - 若动画仍卡顿,打开 Chrome DevTools → Rendering → 勾选 “Paint flashing”,看绿色闪块是否覆盖整个元素;如果有,说明触发了重绘,可能是背景渐变、阴影或字体抗锯齿干扰了合成
transitionend 事件监听不到?注意触发条件
transitionend 只在 transition 真正执行完后触发,而很多情况下它根本没启动——比如目标态和初始态一样、属性不可动画、或 transition 被覆盖。
- 监听前先确认:元素当前
transform值和将要设的值是否不同?用getComputedStyle(el).transform打印看看 - 别在 class 切换后立刻监听,要等下一次事件循环:
setTimeout(() => el.addEventListener('transitionend', handler), 0) - 多个 transition 属性(如同时动
transform和opacity)会触发多次transitionend,需通过event.propertyName === 'transform'过滤 - 如果用 JS 直接设
el.style.transform = 'translateX(100px)',但之前没声明transition,事件也不会触发
移动端 touch 交互中 translate 动画失灵
iOS Safari 和部分安卓 WebView 对 transform + transition 的触发动效更敏感,尤其在快速连续操作时容易“吞掉”第一次动画。
- 给元素加
-webkit-transform: translateZ(0)(或transform: translateZ(0)),强制创建独立合成层,能显著提升 iOS 下的响应稳定性 - 避免在
touchstart中立即修改transform,改为touchend或加setTimeout(..., 0)延迟一帧 - 如果用
position: fixed元素做位移,iOS 下可能因视口缩放导致坐标计算偏差,此时优先改用position: absolute+transform
实际中,最常被忽略的是 transition 的“源头归属”——它不属于动作指令,而是元素自身的视觉状态描述。写错位置、漏写初始值、混用 layout 属性,三者任一都会让平滑位移变成瞬间跳变。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











