浏览器不支持对 display 属性做过渡,因其只有 none/block/flex 等离散值,无中间状态;应改用 visibility + opacity 组合,并严格对齐切换节奏,初始态需同时设 opacity: 0 和 visibility: hidden,通过 transition-delay 控制 visibility 在 opacity 动画结束时生效。

为什么 transition: display 0.3s 完全没反应
浏览器压根不支持对 display 做插值计算——它只有 none、block、flex 等离散状态,没有“半显示”这种中间值。你写的那行 transition: display 0.3s 在开发者工具的“计算样式”里根本找不到,不是被忽略,是直接被引擎丢弃。
visibility + opacity 组合怎么写才不闪不卡
关键不在加不加过渡,而在两个属性的切换节奏是否对齐:
-
visibility本身不可插值,但可以配step-end或0s延迟,让它严格卡在opacity动画结束那一刻生效 - 初始态必须同时设
opacity: 0和visibility: hidden,不能只靠opacity隐藏——否则元素仍挡点击 - 显隐切换用 class 控制,别手动改 style,避免浏览器合并重绘跳帧
典型写法:
.fade-el { opacity: 0; visibility: hidden; transition: opacity 0.3s ease, visibility 0s 0.3s; }
.fade-el.show { opacity: 1; visibility: visible; transition-delay: 0s; }
visibility: hidden 和 pointer-events: none 到底该选哪个
它们都让元素“点不了”,但底层机制完全不同,混用会出事:
-
visibility: hidden:元素还在文档流里占位,子元素默认继承隐藏,且 完全不响应任何事件(hover/click 都无效) -
pointer-events: none:元素视觉照常(或靠opacity隐藏),但鼠标事件穿透到下层;子元素也继承,但可单独加pointer-events: auto拉回来
过渡场景中无脑选 visibility 更安全;只有遮罩层要透出底下按钮这类特殊需求,才考虑 pointer-events。
动画结束后要不要真设 display: none
取决于你是否需要释放布局空间或配合可访问性:
- 如果只是淡入淡出,
visibility + opacity已足够,不用动display - 若要真正卸载(比如模态框关闭后释放 DOM 占用)、或父容器有
overflow: hidden导致占位引发滚动条抖动,就得监听transitionend事件,在回调里补上display: none和aria-hidden="true" - 注意:JS 设置
display: none后,记得同步清理tabindex或焦点管理,否则键盘用户可能卡在不可见元素上
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











