flexbox中visibility: hidden和visibility: collapse有什么区别?

16
CSS弹性盒子布局模块中,它说:
收缩的 flex 项目完全从渲染中移除,但留下一个“支架”。
那是否就像 visibility: hidden 一样?如果是,那么为什么要引入 visibility: collapse
2个回答

32
Note on browser support: 截至2017年7月,Chrome(59)不支持visibility: collapse。下面的代码示例在Firefox和Edge中使用collapse可以工作,但在Chrome中会失败(它们的行为就像hidden)。更新:截至2020年7月,这个说明仍然有效。Chrome和Safari将visibility:collapse视为hiddencaniuse.com

flex-direction决定了Flex项目是按行还是按列进行布局。

每一行/列都被视为一个flex line

在下面的示例中,flex容器在row-direction中有四个flex项。第四项换行,创建第二个flex line:

.container {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  border: 1px dashed black;
}
.box {
  height: 50px;
  flex: 0 0 50px;
  margin: 5px;
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="container">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
  <div class="box box4">4</div>
</div>

display: none

display: none 属性可以使得弹性项目在浏览器中不呈现。

当一个弹性线上的所有项目都使用了display: none属性时,该行将会折叠,并影响其余布局。当弹性线折叠时,周围的元素可能会发生移动。

如果第三项应用了display: none属性,第四项将顶替它在上面的行,并且下面的行将折叠:

.container {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  border: 1px dashed black;
}
.box {
  height: 50px;
  flex: 0 0 50px;
  margin: 5px;
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box3 { display: none; }
<code>display: none</code>
<div class="container">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
  <div class="box box4">4</div>
</div>

visibility: hidden

visibility: hidden 属性可以让一个弹性项目在浏览器中被渲染,但完全透明。它不可见,但在布局中仍占用正常空间。因此,周围的元素仍将其视为完整。

在这个例子中,当最后两个框具有 visibility: hidden 属性时,布局的其余部分(包括第二行弹性)保持不变。

.container {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  border: 1px dashed black;
}
.box {
  height: 50px;
  flex: 0 0 50px;
  margin: 5px;
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box3 { visibility: hidden; }
.box4 { visibility: hidden; }
<code>visibility: hidden</code>
<div class="container">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
  <div class="box box4">4</div>
</div>

visibility: collapse

visibility: collapse使得弹性项目不被渲染(与display: none相同),但弹性算法会检查该项目的交叉尺寸,然后使用这些数据来保持弹性行的稳定性(即如果弹性项目可见,则该行的交叉尺寸是多少)。

display: none的区别在于,collapse允许项目的一部分-其交叉尺寸-被保留。规范中称之为支柱

因此,如果行上的所有弹性项目都具有visibility: collapse,则该行的交叉尺寸(无论是宽度还是高度)不会折叠,布局的其余部分也不会受到影响。

请注意,尽管collapse确保了行的交叉尺寸的稳定性,但它对行的主尺寸没有任何保证。这是collapsehidden之间的关键区别。

以下是一些示例(如上所述,这些示例在Chrome中不起作用,请在FF或Edge中测试)。

在此示例中,前两个项目具有visibility: collapse

.container {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  border: 1px dashed black;
}
.box {
  height: 50px;
  flex: 0 0 50px;
  margin: 5px;
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box1, .box2 {
  visibility: collapse;
}
<code>visibility: collapse</code>
<div class="container">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
  <div class="box box4">4</div>
</div>

布局呈现为display: none。第二行会塌陷,因为项目的主要尺寸已经消失,从而让最后一个项目自然上移。
在以下示例中,所有项目都获得了visibility: collapse。因此,第二行会塌陷,因为项目的主要尺寸已经消失,但是第一行的交叉尺寸仍然存在。

.container {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  border: 1px dashed black;
}
.box {
  height: 50px;
  flex: 0 0 50px;
  margin: 5px;
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box {
  visibility: collapse;
}
<code>visibility: collapse</code>
<div class="container">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
  <div class="box box4">4</div>
</div>

jsFiddle


1
简而言之:由于visibility: hidden实际上不影响布局,所以它们并不相同。 - BoltClock
非常感谢!规范说明 WebKit 通过了折叠项的测试,因此我认为 Chrome 的行为是正确的,并没有在 Firefox 和 Edge 上进行测试。再次感谢! - everywill

0

这实际上取决于元素。如果用于表格子元素,collapse将隐藏该元素以及它占据的空间。

如果在非表格子元素上使用collapse,它将像hidden一样行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接