transition仅对可计算插值的CSS属性有效,如opacity、transform、width等;display等离散属性无效;应避免transition:all,优先用transform/opacity提升性能。

transition 用在哪些 CSS 属性上才有效
transition 不是万能的,它只对「可计算、可插值」的 CSS 属性起作用。比如 opacity、transform、width、height、background-color 可以,但 display、visibility、z-index 这类离散型属性加了也没反应。
常见误操作:给 display: none → block 加 transition,结果动画完全不触发——因为 display 没有中间状态。
- 优先用
opacity+transform替代display控制显隐和位移 - 颜色过渡推荐用
hsl()或rgba(),比rgb()更平滑(避免十六进制色值) - 批量过渡多个属性时,别写
transition: all 0.3s,容易意外触发非预期属性变化
hover 触发动画的写法和兼容性注意点
最常用的是 hover 状态过渡,但要注意:必须在「初始态」就声明 transition,否则 hover 时不会产生动画效果。
.card {
opacity: 0.8;
transform: translateY(0);
transition: opacity 0.2s ease, transform 0.3s ease; /* ✅ 这里定义 */
}
.card:hover {
opacity: 1;
transform: translateY(-4px); /* ✅ hover 仅改值,不重复写 transition */
}容易踩的坑:
立即学习“前端免费学习笔记(深入)”;
- 旧版 Safari(transform 的
translateZ或复合scale+rotate支持不稳定,建议拆开或降级为translateY - 移动端没有
:hover,需要配合:active或 JS 添加 class 来模拟 - 不要在
:hover里写transition: …,浏览器会忽略
transitionend 事件监听的实际用途
当需要在动画结束后执行 JS 操作(比如切换 class、加载内容、重置状态),得靠 transitionend 事件,而不是靠 setTimeout 估算时间。
关键点:
- 事件名是
transitionend,不是webkitTransitionEnd(现代浏览器已统一支持) - 一个元素多个属性过渡时,该事件可能触发多次,需用
event.propertyName判断是哪个属性结束 - 务必用
element.addEventListener('transitionend', handler, { once: true })防止重复绑定
button.addEventListener('transitionend', (e) => {
if (e.propertyName === 'opacity') {
button.textContent = 'Done!';
}
}, { once: true });性能敏感场景下 transition 的取舍
动画卡顿往往不是因为没加 transition,而是加错了属性。浏览器重绘(repaint)和重排(reflow)代价高,而 transform 和 opacity 是由合成器(compositor)单独处理的,几乎不触发重排。
- 要动位置,用
transform: translateX(),别用left/margin-left - 要动透明度,用
opacity,别用rgba(a)改 alpha 值(虽然也行,但部分安卓 WebView 有渲染瑕疵) - 过渡时间别设太长(>0.5s),尤其在移动设备上,用户感知延迟明显
- 慎用
box-shadow过渡,低端机上掉帧严重;可用backdrop-filter+opacity替代毛玻璃入场效果
真正难的不是写出来,是判断哪一步该用 transition、哪一步该交给 JS 动画库(比如需要弹簧效果、中断重播、多段时序时,transition 就力不从心了)。










