transition生效需同时满足三点:目标属性支持动画、正确设置transition相关属性、该属性值确有变化;最简写法为transition: opacity 0.3s ease;background-color过渡失败常因颜色格式不一致;慎用transition: all;js触发时需避免重排被跳过。

transition 基本写法和必要条件
transition 不会自动生效,它只在元素的某个 CSS 属性值发生“变化”时才起作用。常见触发场景是 :hover、:focus、JavaScript 动态修改 class 或内联样式。
必须同时满足三点才能看到过渡效果:
- 目标属性本身支持动画(比如
color、opacity、transform、width 等;但 display、height(非 0 ↔ 非 0)等不推荐直接过渡)
- 设置了
transition 或其子属性(transition-property、transition-duration、transition-timing-function、transition-delay)
- 该属性的值在两个状态之间确实发生了变化(例如从
opacity: 1 → opacity: 0)
color、opacity、transform、width 等;但 display、height(非 0 ↔ 非 0)等不推荐直接过渡)transition 或其子属性(transition-property、transition-duration、transition-timing-function、transition-delay)opacity: 1 → opacity: 0)最简可用写法:
button { transition: opacity 0.3s ease; }<br>button:hover { opacity: 0.6; }
为什么改了 background-color 却没过渡?
background-color 支持过渡,但容易被忽略的是:**颜色值必须可插值**。比如从 red 到 hsl(120, 100%, 50%) 没问题,但从 transparent 到 rgba(0,0,0,0.5) 在某些旧浏览器中可能跳变。
更稳妥的做法:
- 统一用
rgb() 或 hsl() 表示起始/结束色,避免关键字与 rgba 混用
- 确保 alpha 通道都显式声明(比如都用
rgba),否则浏览器可能 fallback 到不透明色再插值
- 不要对
background-image 做过渡——它不支持,会直接切换
rgb() 或 hsl() 表示起始/结束色,避免关键字与 rgba 混用rgba),否则浏览器可能 fallback 到不透明色再插值background-image 做过渡——它不支持,会直接切换示例(可靠写法):
.box {<br> background-color: rgba(255, 0, 0, 0.8);<br> transition: background-color 0.4s linear;<br>}<br>.box.active {<br> background-color: rgba(0, 128, 255, 0.8);<br>}
transition-property 设为 all 有什么风险?
transition: all 0.2s; 看似省事,实际容易引发意外行为:
- 无意中过渡了不该动的属性(比如
box-shadow、font-size 在响应式中被 JS 修改,导致卡顿)
- 部分属性过渡开销大(如
width、height 触发 layout,top/left 触发 paint,而 transform 和 opacity 只走 composite,更流畅)
- 多个属性过渡时间/函数不一致时,
all 会强制统一,丧失控制精度
box-shadow、font-size 在响应式中被 JS 修改,导致卡顿)width、height 触发 layout,top/left 触发 paint,而 transform 和 opacity 只走 composite,更流畅)all 会强制统一,丧失控制精度建议始终显式声明:
.card {<br> transition: <strong>transform</strong> 0.25s cubic-bezier(0.2, 0.8, 0.4, 1),<br> <strong>opacity</strong> 0.25s ease;<br>}
JavaScript 触发 transition 失效的典型原因
用 JS 添加 class 后过渡没反应,大概率是浏览器没“感知到状态差异”。常见坑:
- class 添加后立即读取 offsetHeight / getComputedStyle —— 浏览器来不及重排,过渡被跳过
- 在同一个 event loop 中连续修改同一属性(比如先设
opacity: 0,再设 opacity: 1),中间无重绘机会
- 目标元素初始状态未定义过渡属性(
transition 必须写在“常态”规则里,不能只写在 hover 或 active 中)
opacity: 0,再设 opacity: 1),中间无重绘机会transition 必须写在“常态”规则里,不能只写在 hover 或 active 中)修复方式(强制重排):
el.classList.add('fade-in');<br>// 强制触发一次 layout,让浏览器记住初始状态<br>void el.offsetWidth;<br>el.style.opacity = '1';
过渡不是万能的,真正影响体验的是属性选择——优先用 transform 和 opacity,避开 layout 触发点。其他属性过渡前,先确认是否真有必要。










