transition: display 从未生效,因display是离散属性无中间状态,浏览器直接静默丢弃该声明;应改用opacity+visibility协同控制,并在transitionend中按propertyname精准清理。

直接说结论:transition: display 从来就没生效过,不是你写错了,是浏览器压根不处理——它被静默丢弃,DevTools 的 Computed 面板里根本找不到这条规则。
为什么transition: display 完全没反应
display 是离散属性,取值只有 none、block、flex 等枚举值,没有“50% 显示”这种中间状态可插值。浏览器渲染引擎在解析时直接跳过整条声明,连 warning 都不抛。更关键的是:display: none 会让元素立刻脱离渲染树,连子元素的 opacity 动画都会一并终止。
用 opacity + visibility 替代的实操要点
这不是简单换两个属性,而是分工明确、时机对齐的协同控制:
- 初始态必须同时设
opacity: 0和visibility: hidden,只靠opacity隐藏会挡点击、抢焦点 -
transition必须显式列出两者:transition: opacity 0.25s ease, visibility 0s 0.25s(visibility延迟到opacity动画结束才切换) - 别用
transition: all—— 它不会自动包含visibility,必须手写 - 显示类中要同步设
opacity: 1和visibility: visible,否则元素不可交互
动画结束后要不要补 display: none
取决于你是否需要释放布局空间或满足可访问性要求:
- 如果只是淡入淡出、下拉菜单这类场景,
visibility + opacity已足够,不用动display - 如果内容庞大(如整页弹窗),或父容器有
overflow: hidden导致占位撑开滚动条,就必须在动画结束后补display: none - 监听
transitionend事件,且只在event.propertyName === 'opacity'时执行清理,避免误触发 - 同步设置
aria-hidden="true"并移除tabindex或 blur 当前焦点,否则键盘用户可能卡在不可见元素上
真正容易被忽略的是:DOM 卸载时机与动画完成的错位。哪怕 CSS 写得再准,只要没在 transitionend 里检查 propertyName 并精准清理,就可能留下占位、焦点陷阱或可访问性漏洞。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











