display: none 彻底移除元素,不占空间、不响应事件、不被屏幕阅读器感知;visibility: hidden 仅隐藏视觉,仍占布局空间、可获取尺寸、子元素无法通过 visible 覆盖父级 hidden。

display: none 和 visibility: hidden 的核心区别
二者都能让元素“看不见”,但浏览器对待它们的方式完全不同:display: none 是彻底移除渲染流中的该元素,不占空间、不响应事件、不被屏幕阅读器感知;visibility: hidden 仅隐藏视觉呈现,元素仍占据布局空间、仍可被 getBoundingClientRect() 获取尺寸、父元素设为 hidden 时子元素设 visible 仍可显示(层叠上下文相关)。
什么时候该用 display: none
适用于需要完全排除元素参与布局和交互的场景,比如条件性展示模块、表单步骤切换、响应式断点隐藏组件。
- 页面加载后动态移除某区域(如广告位未加载完成前占位符)
- 使用 JavaScript 控制显隐时,后续需频繁读取该元素尺寸或位置 —— 切记:一旦设为
display: none,offsetTop、clientWidth等会返回0或NaN - SEO 敏感内容(如辅助说明文字)需确保不被索引时,配合服务端逻辑更稳妥,纯前端
display: none不保证搜索引擎忽略
visibility: hidden 的典型用途与陷阱
它更适合“临时遮罩”或“保留占位”的需求,比如 hover 动画过渡、焦点管理、无障碍隐藏(需搭配 aria-hidden="true")。
- 做淡入动画时,先设
visibility: hidden; opacity: 0,再用 CSS transition 改opacity和visibility—— 单独靠opacity无法触发重排,但visibility变化会 - 父元素设
visibility: hidden,其子元素即使设visibility: visible也**不会显示**(这是继承行为,不是层叠),这点和display完全不同 - 元素设
visibility: hidden后仍能接收focus()、响应keydown(如果 tabIndex >= 0),容易造成键盘导航逻辑混乱
实操对比示例
以下代码可直接保存为 test.html 在浏览器中打开观察差异:
立即学习“前端免费学习笔记(深入)”;
AB (display: none)C (visibility: hidden)D
注意看 B 和 C 周围的间距:B 消失后 A 与 D 紧邻,C 消失后 A 与 D 之间仍保留 C 的空白间隙。这就是布局是否参与的关键证据。
复杂点在于混合使用:比如在动画中同时控制 display 和 visibility,必须严格按顺序 —— 先设 visibility: hidden,再设 display: none(否则后者会让前者失效);反向恢复时则相反。稍有错序就会出现闪现或卡顿。










