CSS transition 初次加载不自动触发,仅在属性值真实变化时生效;常见“加载即动”实为JS或class切换导致的状态变更,需确保transition声明早于首次属性修改且写在基础样式中。

CSS transition 在页面初次加载时不会自动触发——它根本不会动,除非你手动改了某个属性值。 所有“一打开就动”的现象,都是因为初始样式和后续 JS 或 class 切换导致的属性变化被误认为是“自动触发”,其实是过渡在响应真实的状态变更。
transition 为什么看起来像“加载就动”
常见错觉来源:你写了 transition: opacity 0.3s,又给元素设了 opacity: 0 初始状态,然后 JS 在 DOMContentLoaded 里立刻加了个 .loaded 类,把 opacity 改成 1。这不是“自动触发”,而是 JS 显式触发了一次属性变化。
- 浏览器不会在解析 CSS 时主动执行 transition
- transition 生效的充要条件只有两个:
transition声明存在 + 对应属性值发生改变 - 如果没 JS、没 :hover、没 class 切换,哪怕写了 10 遍
transition,页面加载完也纹丝不动
如何防止“意外入场动画”
真正需要防的不是“自动触发”,而是“你不希望发生的首次变化”。比如你用 JS 控制显隐,但初始 DOM 就带 opacity: 1,结果 JS 一上来又设一次 opacity: 1,看似没变,实则可能因重排/重绘触发过渡(尤其配合 transform 时)。
- 初始状态避免写可动画属性的“中间值”,比如不要设
opacity: 0.5,而用opacity: 0或opacity: 1 - JS 修改样式前,先移除
transition声明(临时加 class 禁用),改完再恢复,例如:el.classList.add('no-transition');→ 修改opacity→el.classList.remove('no-transition'); - 如果目标是“完全静默加载”,初始 HTML 元素直接不写任何可动画属性(如不设
transform、opacity),等 JS 准备好后再统一注入
transition 写在哪儿才安全
必须写在基础样式(即默认状态)里,不能只写在 :hover 或 .active 这类触发类中。否则,当 JS 移除那个类时,transition 声明随之消失,浏览器失去起始参考,动画直接跳变。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确:
.card { opacity: 0; transition: opacity 0.4s ease; }+.card.show { opacity: 1; } - ❌ 错误:
.card:hover, .card.show { transition: opacity 0.4s ease; opacity: 1; }—— 移除.show后,transition没了,收起动作就没了过渡 - 注意:
transition是继承性极弱的属性,不要指望父级声明能作用到子元素
最容易被忽略的一点:transition 不是“开关”,它是“监听器”。你删了它,就等于关掉了监听;你晚一秒加它,之前的变化就永远无法补上动画。所以 JS 动态控制时,transition 声明必须比第一次属性修改更早存在于计算样式中。


















