display: none 彻底移除元素,不占布局空间、无尺寸、子元素不可见、表单字段不提交、屏幕阅读器跳过;visibility: hidden 仅视觉隐藏,保留布局位置、尺寸可读、子元素可显式显示、事件仍可触发。

直接说结论:display: none 是“删掉盒子”,visibility: hidden 是“关灯但盒子还在原地”。选哪个,取决于你要不要保留布局位置、是否需要 JS 读取尺寸、要不要让子元素意外显示出来。
display: none 彻底移除渲染节点,不占空间也不参与布局
浏览器在构建 Render Tree 时就跳过它,所以它没有盒模型、没有 offsetHeight、getBoundingClientRect() 返回全 0。父元素设了 display: none,所有子元素无论怎么设置 display 都无效——它们根本不会被渲染。
- 表单中如果用
display: none隐藏<input>,提交时该字段会被忽略(不是只看不见,是压根不进 FormData) - 屏幕阅读器默认跳过
display: none元素,SEO 也基本不索引 - 反复切换
display容易触发 layout thrashing:比如在 for 循环里先读offsetHeight再设display: none,浏览器被迫同步重排多次 - 动画场景慎用:直接从
display: block切到display: none无法过渡,会“啪”一下消失
visibility: hidden 保留盒模型,仅视觉隐藏且可被子元素打破
元素仍在文档流中,宽高、margin、padding 全部照算,周围元素纹丝不动。offsetHeight 返回真实值,适合依赖尺寸的 JS 逻辑(比如计算 tooltip 位置)。
- 子元素只要显式写
visibility: visible就能“钻出来”显示——这是最常踩的坑:父层加了visibility: hidden,结果某个图标或文字漏出来了 - 它不阻止事件捕获/冒泡,鼠标悬停或点击仍可能命中(只是用户看不到反馈),真要禁交互得额外加
pointer-events: none - 和
opacity: 0不同:它不透明,也不响应点击;而opacity: 0既占位又可点,语义完全不对 - 适合做预占位的过渡效果,比如下拉菜单展开前先
visibility: hidden占好位置,再配合opacity做淡入
两者同时设置时,display 永远胜出
CSS 层叠规则里 display 的优先级高于 visibility。哪怕你写成 display: none; visibility: visible;,元素照样不显示、不占位。
- JS 动态设置时要注意顺序:
el.style.visibility = 'hidden'; el.style.display = 'none';后者生效;反过来的话,display可能被后续样式覆盖 - 极少需要两者共存,但如果用了(比如 CSS 类叠加 + JS 覆盖),别指望
visibility能“救”回一个display: none的元素 - 调试时看开发者工具的 Computed 面板,
display值为none就不用再查visibility了
真正容易被忽略的是继承行为和事件穿透:子元素对 visibility 的继承是隐式的,一不留神就“漏内容”;而 display: none 看似彻底,却可能让表单字段丢数据、让键盘焦点失效——这些都不是“看不见”那么简单的事。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











