最根本差异是元素是否仍在文档流中:display:none使元素彻底退出文档流、不占空间、触发重排;visibility:hidden仅视觉隐藏,元素仍占位、参与布局、仅触发重绘。

元素是否还在文档流里
这是最根本的差异。display: none会让元素彻底退出文档流,浏览器渲染时直接跳过它;visibility: hidden只是“关掉显示开关”,元素仍在流中、仍参与布局计算。
常见错误现象:轮播图切换时用display: none隐藏非当前页,结果容器高度塌缩、下方内容上跳;换成visibility: hidden后布局就稳了。
-
display: none下,offsetHeight、getBoundingClientRect()返回0或空对象 -
visibility: hidden下,这些值仍是真实尺寸,getComputedStyle(el).visibility返回"hidden" - 表格中隐藏某单元格时,用
visibility: hidden可避免整行错位
子元素能不能自己“挣脱”出来
visibility具有继承性,但子元素能通过显式设置visibility: visible恢复显示;display: none一票否决,子元素再怎么设display: block也无效。
使用场景:弹窗遮罩层用visibility: hidden,里面某个按钮需单独显示(比如“跳过引导”)——直接给按钮加visibility: visible就行;若遮罩层用display: none,整个结构就得重挂载。
立即学习“前端免费学习笔记(深入)”;
- 父元素
visibility: hidden→ 子元素visibility: visible→ 子元素可见 - 父元素
display: none→ 子元素display: block→ 子元素依然不可见 - React/Vue 中用
v-show本质就是切display,不是visibility
会不会触发重排(reflow)
display: none改变的是元素是否存在,浏览器必须重新计算布局,触发重排;visibility: hidden只影响绘制阶段,仅重绘(repaint),开销小得多。
性能敏感场景(如高频滚动中动态显隐):频繁切display可能卡顿,visibility更稳妥。但注意:visibility配合opacity做淡入动画时,visibility本身不支持过渡,得靠opacity驱动。
- 动画过渡中临时隐藏某部分,优先选
visibility: hidden+opacity: 0 - 完全移除一个模块(如关闭侧边栏),用
display: none更干净 - 老版本 IE(IE8-)对
visibility: hidden在table-cell上有渲染 bug,需避开
屏幕阅读器和事件响应是否受影响
display: none的元素对辅助技术完全不可见,也不响应任何事件;visibility: hidden默认仍会被屏幕阅读器读取,且能响应click等事件(虽然看不见)。
无障碍关键点:如果用visibility: hidden隐藏关键操作区域(比如表单字段),必须同步加aria-hidden="true",否则读屏软件会误报。
-
display: none→ 事件绑定失效,pointer-events: none也无需额外加 -
visibility: hidden→ 事件仍可触发,但用户看不到反馈,容易引发误操作 -
details/summary元素上慎用display: none,可能破坏原生展开逻辑
display: none和visibility: hidden的底层行为。


















