transition-delay失效主因有四:简写覆盖、初始值缺失、伪类位置错误、节点序号漂移;需统一声明、显式设初始值、延迟写在默认状态、慎用:nth-child。

transition-delay 设置了但没效果,大概率是被覆盖了
浏览器只认最后解析到的那条完整 transition 声明,前面的整条都会丢弃——包括其中的 transition-delay。哪怕你写了两行,第二行只要用了简写,就会把第一行的 delay 重置为 0s。
- ❌ 错误写法:
.box { transition: opacity 0.3s ease 0.5s; transition: transform 0.2s ease; }→ 第二行覆盖第一行,opacity的 delay 归零 - ✅ 正确写法:
.box { transition: opacity 0.3s ease 0.5s, transform 0.2s ease 0.5s; }→ 显式保留每个属性的 delay - 更稳妥的方式是拆开写:
transition-property、transition-duration、transition-timing-function、transition-delay分开定义,避免简写覆盖
JS 添加 class 后 transition-delay 被跳过,因为没触发重排
JavaScript 同步修改 DOM 和样式时,浏览器可能把“加 class”和“计算新样式”合并到同一帧,导致 transition-delay 根本没机会启动。
- 错误写法:
el.classList.add('active'); getComputedStyle(el).opacity;→ 这句读取会强制同步 layout,反而干扰过渡队列 - ✅ 推荐做法:用
setTimeout(() => el.classList.add('active'), 0)或requestAnimationFrame(() => el.classList.add('active')) - 注意:
requestAnimationFrame只解决“时机”,不补“缺失的起点”——如果opacity初始值没在 CSS 里显式声明(比如漏了opacity: 0;),加 rAF 也白搭
hover 场景下 transition-delay 失效,是因为只写在 :hover 里
transition-delay 必须定义在初始状态(比如默认类或元素选择器),而不是只写在 :hover 规则中。后者会被视为“状态切换后才加的 transition”,不参与本次过渡。
- ❌ 错误:
.btn { opacity: 0; } .btn:hover { opacity: 1; transition: opacity 0.3s ease 0.2s; }→ hover 里的 delay 不生效 - ✅ 正确:
.btn { opacity: 0; transition: opacity 0.3s ease 0.2s; } .btn:hover { opacity: 1; } - 如果想进有延迟、出无延迟,需在 hover 状态显式重置:
.btn:hover { opacity: 1; transition-delay: 0; }
多个元素交错入场时,:nth-child(n) 的延迟值容易错位
用 :nth-child 配合 transition-delay 实现 stagger 效果时,节点结构稍一变化(比如插入注释、文本节点、其他标签),序号就全乱了。
- 别用
:nth-of-type替代:nth-child,除非父容器里只有目标元素且顺序严格可控 - 动态生成的列表建议改用 CSS 自定义属性:
style="--delay: 0.15s"+transition-delay: var(--delay, 0s) - Safari 对
var()在transition-delay中的支持直到 iOS 15.4 才稳定,老版本会退化为无延迟
transition-delay 就静默失效。它不报错,也不警告,只默默跳过。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











