display 不支持 transition,因其取值无数值关系;需用 opacity+visibility 协同:初始设 opacity:0 和 visibility:hidden,transition 显式声明两者,动画结束监听 transitionend 并精准清理。

因为 display 是离散属性,浏览器根本不支持对它做插值计算——你写的 transition: display 0.3s 会被静默丢弃,DevTools 的 computed 面板里都找不到这条规则。
为什么 display 完全不触发 transition
display 的取值(none、block、flex 等)之间没有数值关系,无法生成“50% 显示”这类中间帧。动画引擎直接跳过它,起始态一设成 display: none,元素立刻脱离渲染树,连带子元素的 opacity 动画也会被强制中止。
opacity + visibility 必须显式协同写法
这不是换两个属性就行,而是分工+时机必须对齐:
- 初始隐藏态要同时设
opacity: 0和visibility: hidden,否则opacity: 0时仍挡点击 -
transition必须显式列出两者:transition: opacity 0.25s ease, visibility 0s 0.25s(visibility延迟生效,卡在opacity结束那一刻) - 别用
transition: all—— 它不会自动包含visibility,必须手动写 - 显示时先加
visibility: visible(防点击穿透),再设opacity: 1
动画结束后要不要真设 display: none
取决于是否需要释放布局空间或满足可访问性要求:
- 如果父容器有
overflow: hidden,visibility: hidden仍占位,可能撑出滚动条或导致重绘抖动 - 此时必须监听
transitionend事件,并只在event.propertyName === 'opacity'时执行:el.style.display = 'none'和el.setAttribute('aria-hidden', 'true') - 记得同步移除
tabindex或调用el.blur(),否则键盘焦点可能卡在不可见元素上 - JS 中绝对不要在动画进行中同步写
el.style.display = 'none',否则过渡直接中断
真正难处理的不是怎么写 CSS,而是 DOM 卸载时机和动画完成之间的错位——哪怕样式全对,只要没在 transitionend 里检查 propertyName 并精准清理,元素就一直占着文档流、拖慢渲染、干扰屏幕阅读器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











