transition仅在可过渡属性真实变化时触发,如opacity、transform等;display/visibility/height:auto等不可过渡,all易引发性能与调试问题,应显式声明属性。

transition 不是动画播放器,它只响应「属性值实际发生变化」的那一刻。如果你写了 transition: opacity 0.3s,但 opacity 始终没变(比如用 visibility: hidden 控制显隐),那什么都不会动。
transition 触发的必要条件:属性必须可过渡且真实改变
不是所有 CSS 属性都能被 transition 管理。浏览器只支持对「可计算、可插值」的属性做平滑过渡,比如:opacity、transform、color、width(需有明确单位)、background-color(需同类型颜色值,如都用 rgb() 或都用十六进制)。
以下情况不会触发过渡:
-
display: none→display: block:display 不可过渡,元素会直接闪现 -
visibility: hidden→visibility: visible:visibility 不可过渡,只是开关式显隐 -
height: 0→height: auto:auto 无法参与插值计算,过渡会失效或卡在 0 - 从
rgba(0,0,0,0)切到transparent:类型不一致,部分浏览器可能拒绝插值
多个属性过渡要分开写,别偷懒用 all
写 transition: all 0.2s ease 看似省事,但隐患很大:
- 意外过渡:比如
box-shadow或z-index被动变化也会动,干扰预期行为 - 性能问题:某些属性(如
width、top)触发布局重排(reflow),而transform和opacity只触发合成(compositor),后者更高效 - 调试困难:某个属性突然“自己动了”,你得翻半天样式才意识到是
all捞过界了
推荐写法是显式声明关键属性:transition: opacity 0.2s ease, transform 0.2s ease;
立即学习“前端免费学习笔记(深入)”;
transition-delay 的生效时机容易误解
transition-delay 不是“等 X 秒再开始过渡”,而是“等 X 秒后,**下一次属性变化**才启用过渡”。这意味着:
- 如果元素刚加载时就带最终状态(比如服务端渲染出
class="active"),那没有「变化过程」,delay完全无效 - JS 批量修改多个属性时,浏览器会合并重绘,
delay是从**整个变更批次结束时刻**开始计时,不是从第一个属性改起算 - hover 场景下,
transition-delay: 0.1s表示鼠标停稳 100ms 后才启动过渡——适合防误触,但用户快速划过会完全没反应
用 opacity + transform 实现真正流畅的显隐/位移
想让元素淡入+上浮,别碰 margin 或 top,它们会引发 layout;优先选组合:
-
opacity控制透明度(支持硬件加速,无重排) -
transform: translateY(-8px)控制位移(同样走合成层,不打断渲染流水线)
示例:
.item {
opacity: 0;
transform: translateY(10px);
transition: opacity 0.25s ease-out, transform 0.25s ease-out;
}
.item.show {
opacity: 1;
transform: translateY(0);
}
注意:初始状态和目标状态都要定义完整,否则浏览器可能按默认值补间(比如未设 transform 时默认为 none,但 none 和 translateY(0) 在部分旧版 Safari 中插值表现不一致)。


















