跳到主要内容

display: nonevisibility: hidden 的区别?

面试速答(30 秒版 TL;DR)

  • display: none:元素不生成盒子(box),相当于从布局里移除,不占空间;整棵子树都不会渲染,子元素无法“单独显示”。
  • visibility: hidden:元素仍占据布局空间,只是不绘制visibility可继承的,子元素可显式设为 visibility: visible 重新显示。

核心对比(高频维度)

维度display: nonevisibility: hidden
是否占位❌ 不占位✅ 占位
是否生成盒子❌ 不生成(无 box)✅ 生成但不可见(不绘制)
命中测试/点击❌ 点不到❌ 点不到(点击会落到后面的元素)
可访问性(屏幕阅读器)通常不可通常不可
对子元素的影响子树整体不渲染,无法被子元素覆盖默认影响子元素,但子元素可设 visibility: visible 覆盖
读取布局尺寸(常见 DOM API)offsetWidth/Height 通常为 0仍可读到实际尺寸
切换开销(一般)更可能触发 reflow(布局变化)通常不触发布局,只影响绘制
能否做过渡动画不行(不能平滑过渡到/从 nonevisibility 本身是离散切换,常配合 opacity 做过渡

注:上表是常见规律总结。实际是否触发 reflow/paint 仍取决于页面结构与浏览器优化。

代码例子(最小)

<div class="row">
<span class="a">A</span>
<span class="b">B</span>
</div>
.row {
display: flex;
gap: 12px;
}

/* 1) 不占位:B 直接消失,A 会顶上去 */
.b {
display: none;
}

/* 2) 占位但不可见:B 留下空白 */
/* .b { visibility: hidden; } */

常见追问(面试会顺带问)

Q1:那 opacity: 0 呢?

  • opacity: 0:元素占位,并且默认仍会参与命中测试(也就是“看不见但能点到”)。
  • 想“透明但不可点”,一般配 pointer-events: none;
  • 想“先渐隐,结束后再彻底移除布局”,常见做法是:先用 opacity 过渡,动画结束后再切换 display: none(或切换 visibility)。

Q2:如何避免隐藏/显示导致布局抖动?

  • 需要“保留占位”就用 visibility: hidden(或固定尺寸占位)。
  • 需要“完全移除占位”就用 display: none,但它会影响周围布局,属于预期行为。

易错点/坑

  • visibility: hidden 会留空白,可能导致“列表出现一条空行”或“容器滚动高度不对”。
  • visibility 是继承属性:父元素 hidden 时,子元素如果显式写 visibility: visible 可能会重新显示;想“一刀切”隐藏整个子树,display: none 更彻底。