原文: CSS display:none and visibility:hidden – What's the Difference?

display:nonevisibility:hidden 是 CSS 中的两个样式声明,你可以用它们来隐藏屏幕上的元素。但它们之间有什么区别呢?

在构建应用程序时,有些时候你想在视觉上隐藏元素(不是从 DOM 中删除它们,只是在屏幕上)。你可以用不同的方法来做这件事。

两种常见的方法包括使用值为 none 的 display 属性或值为 hidden 的 visibility 属性。

尽管这两种方法都在视觉上隐藏了元素,但它们使元素响应的方式不同。我将在本文中解释这些差异。

如果你有兴趣,这里有本文的视频版本

我将通过下面的例子来解释这一切是如何进行。

HTML:

<div class="container">
  <div class="block1"></div>
  <div class="block2"></div>
  <div class="block3"></div>
</div>

CSS:

.container {
  padding: 20px;
  width: max-content;
  display: flex;
  border: 1px solid black;
}

.block1,
.block2,
.block3 {
  height: 40px;
  width: 120px;
}

.block1 {
  background-color: rgb(224, 110, 49);
  margin-right: 20px;
}

.block2 {
  background-color: rgb(77, 77, 234);
  margin-right: 20px;
}

.block3 {
  background-color: rgb(12, 154, 142);
}

我们有一个 class 为 containerdiv。这个 div 有三个子 div,其 class 分别为 block1block2block3。我们已经为这些 div 指定了一些样式。第一个 div 子代是 orange,第二个是 blue,第三个是 teal

结果如下:

image-77

如何在 CSS 中使用 display: none

display 属性设置了一个元素的显示方式(如 inlineblock),也决定了一个元素的子元素的布局(如 flexgrid 等等)。

如果该属性的值为 none,那么该元素的显示就被关闭了。这意味着该元素——以及它的子元素——将不会被显示。文档在没有该元素的情况下被渲染,就像它不存在一样。

现在让我们看看 display: none 是如何工作的。下面是一个将此样式应用于 .block2 元素的例子:

.block2 {
  background-color: rgb(77, 77, 234);
  margin-right: 20px;
  display: none;
}

结果如下:

image-78

正如你在这里看到的,.container 元素的宽度已经减少。这就像 .block2 元素不存在一样。因为我们在这个元素上使用了 display:none,它在文档中没有被渲染。所以它在屏幕上的空间被其他元素占据。

我们也可以通过在 .block1 元素上添加 display:none 来测试这一点:

.block1 {
  background-color: rgb(224, 110, 49);
  margin-right: 20px;
  display: none;
}

.block2 {
  background-color: rgb(77, 77, 234);
  margin-right: 20px;
  display: none;
}

结果如下:

image-79

这里你看到 .block1 .block2 没有被渲染,所以它们的空间被占用。

如何在 CSS 中使用 visibility: hidden

visibility 属性,顾名思义,指定了一个元素是否可见。但是,这个属性并不影响元素的布局。这是与 layout 属性相比的主要区别。

如果这个属性的值是 hidden,它所应用的元素就会变得不可见。元素的盒子模型所需的空间保持不变,但元素本身被隐藏。

让我们看看这个属性如何被应用于我们上面的例子。下面是这个样式应用于 .block2 元素的结果:

.block2 {
  background-color: rgb(77, 77, 234);
  margin-right: 20px;
  visibility: hidden;
}

结果如下:

image-80

正如你在这里注意到的,与 display: none 不同,.block2 元素是不可见的,但其布局保持不变。事实上,这个元素上的 margin-right 仍然存在。只有这个元素本身被隐藏了。

让我们也给 .block1 添加这个样式,看看结果如何:

image-81

现在这两个元素都是不可见的,但它们仍然在文档中被渲染,所以它们的空间并没有空出来。

接下来你可能会想,“visibility: hiddenopacity: 0 之间有什么区别呢?”

visibility: hidden vs opacity: 0

这两种样式看起来非常相似。我可以通过在我们上面的例子中把 visibility:hidden 替换为 opacity:0 来告诉你:

.block1 {
  background-color: rgb(224, 110, 49);
  margin-right: 20px;
  opacity: 0;
}

.block2 {
  background-color: rgb(77, 77, 234);
  margin-right: 20px;
  opacity: 0;
}

结果如下:

image-82

你可以看到,这个结果和之前的结果在视觉上没有区别。但在元素的行为上是有区别的。

具有 visibility: hidden 的元素是不可交互的。我不知道这是不是最好的说法,但我的意思是,用户不能与这样的元素互动(例如,通过点击)。这是因为这种元素确实是不可见的。

具有 opacity: 0 的元素是可以互动的,因为它们实际上是可见的,只是非常透明。opacity 属性并不指定一个元素的可见性——它只指定透明度。

我们可以用一个例子来验证这个区别。假设 .block2 元素有一个这样的 onclick 属性:

<div class="block2" onclick="alert('hello')"></div>

如果你在这个元素上使用 visibility:hidden,点击这个元素所在的空间将不会触发什么。但如果你在这个元素上使用 opacity:0,点击同样的空间将触发警报模式,显示 “hello” 文本。你可以在你的浏览器上测试一下,实际看看这个效果。

display:nonevisibility:hidden 的使用示例

这些样式声明可以根据你想实现什么被用于不同的场景。

在我的经验中,当我想隐藏一些内容时,我使用 display:none。想想隐藏一个弹出框、UI 上已经被选中的待办事项,或者页面上的侧边栏。

对内容使用 visibility:hidden 会导致内容的空间被保留,当页面上有空白区域时,会显得有些奇怪。

我唯一使用 visibility:hidden 的时候是当我想在“隐藏”或“显示”一个元素时显示一些动画。display 属性不会在数值之间产生动画,但 visibility 属性可以。我将 visibilityopacity 结合起来使用,以实现这种淡入和淡出的动画。

总结

概括地说,display:nonevisibility:hiddenopacity:0 可以被用来视觉上隐藏元素,但是:

  • display:none 关闭元素的布局,所以元素不被渲染
  • visibility:hidden 隐藏元素,而不改变它们的布局
  • opacity:0 使元素非常透明,但是用户依然可以和元素交互

如果你喜欢这篇文章,请将它分享给其他学习者。😇