transition未生效的根本原因是声明位置或初始值错误:transition必须写在常态元素上而非:hover等状态中,且目标属性需有明确初始值,否则浏览器无法构建过渡上下文。

根本原因不是transition-duration没生效,而是浏览器压根没进入过渡流程——时长设对了,但起点、属性或声明时机全错了。
transition-duration 写对了但整条规则被忽略
transition-duration必须带单位(0.3s或300ms),否则整条transition声明会被浏览器静默丢弃,连警告都没有。
-
transition-duration: .3❌ 缺单位,无效 -
transition-duration: 0.3❌ 同样无效 -
transition-duration: 0s✅ 合法,但动画不播放(即“立即切换”) - 只写
transition-duration: 0.2s没用,它必须和transition-property或完整transition简写一起出现
transition 写在:hover里,第一次变化永远没动画
如果transition只出现在:hover、.active这类状态类中,那第一次鼠标移入或JS加类时,浏览器根本没有“起始过渡上下文”,直接跳变到终态。
- ❌ 错误:
.btn:hover { background-color: #007bff; transition: background-color 0.3s; } - ✅ 正确:
.btn { transition: background-color 0.3s; }+.btn:hover { background-color: #007bff; } - 验证方法:打开 DevTools → Elements → Computed 面板,搜索
transition-property,确认它在元素“常态”下就存在
目标属性没有显式初始值,插值无从谈起
过渡需要明确的起点。如果opacity、transform、left等属性在基础样式里根本没声明,浏览器拿到的是auto或initial,无法计算中间帧。
立即学习“前端免费学习笔记(深入)”;
- 常见表现:第一次 hover 或 JS 切 class 是“啪”一下到位,第二次才动起来
- 必须显式写:
.box { opacity: 1; transform: translateY(0); left: 0; transition: opacity 0.3s, transform 0.3s; } - 特别注意:
transform: none和transform: translateY(-10px)类型不匹配,某些浏览器会拒绝过渡
JS 动态加 class 后 transition 瞬间失效
JS 批量操作 DOM 后立即加 class,浏览器还没完成首帧样式计算,就收到了终态指令,导致过渡上下文缺失。
- 不要同步写:
el.classList.add('active'); el.style.opacity = '1'; - 稳妥做法:用
requestAnimationFrame延迟到下一帧再加 class - 更可靠方案:把
transition抽到一个永不被移除的基础类里(如.fade-el { transition: opacity 0.4s; }),状态类只管值 - 避免混用内联 style ——
el.style.transition = 'opacity 0.3s'会覆盖 CSS 中的声明,哪怕只存在一帧,动画链就断了
真正卡住人的从来不是“怎么写 duration”,而是“transition 声明是否从变化前就稳稳挂在元素上”,以及“起点值是不是浏览器能算出来的数字”。


















