应优先使用 visibility: hidden 而非 display: none,因其保持布局位置、不触发重排、保留 dom 尺寸信息及可访问性;但需配合 pointer-events: none 禁用交互,且不支持 css 过渡。

直接用 visibility: hidden 就行,它专为“藏人不挪位”而生。
为什么不能用 display: none?
display: none 会把元素从渲染树里彻底踢出去——盒模型不计算、尺寸不占位、后续元素立刻上移,页面会“抖一下”。这在轮播图预加载、表单错误提示、骨架屏占位等场景中极易引发布局跳动或交互错位。而 visibility: hidden 只是让元素“闭眼站原地”,布局流完全不受影响,只触发重绘(repaint),不触发重排(reflow)。
-
display: none下,el.offsetParent返回null,el.getClientRects()返回空集合 -
visibility: hidden下,上述 API 仍返回有效值,方便 JS 做尺寸判断或动画准备 - SEO 和屏幕阅读器默认仍能访问
visibility: hidden元素(如需屏蔽,得加aria-hidden="true")
visibility 的合法值和继承行为
visibility 只有三个标准值:visible、hidden、collapse(后者仅对表格行/列生效,其他元素等同 hidden)。别写 visibility: false 或 visibility: off,浏览器直接忽略,退回到 visible。
- 父元素设了
visibility: hidden,子元素默认也看不见——这不是 bug,是规范定义的继承行为 - 但你可以显式覆盖:子元素写
visibility: visible就能单独显示(哪怕父级是hidden) -
visibility: collapse在非表格元素上兼容性差,不建议用
怎么配合事件和动画一起用?
visibility 本身不支持 transition(它是离散值),但可以和 opacity 或 transform 组合实现视觉过渡:
- 想隐藏时禁用点击?必须加
pointer-events: none,否则visibility: hidden的元素仍可响应focus或键盘操作 - 要渐隐效果?用
opacity: 0+transition: opacity 0.25s更合适;visibility适合开关式硬切 - 注意堆叠上下文:
opacity: 0.99会创建新层叠上下文,影响z-index行为;visibility: hidden不会
真正容易被忽略的性能细节
当父容器用了 contain: layout style 或 will-change: visibility 时,visibility 切换性能更稳;但若隐藏的是巨型列表,光靠 visibility 不够,得结合虚拟滚动或 DOM 卸载策略。另外,visibility: hidden 下的 <input> 仍可被 focus() 调用,也会计入 document.querySelectorAll('input') 结果——这点常被当成“已卸载”误判。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











