是什么导致flex元素和inline-block元素的宽度不同?

时间:2019-02-20 12:34:11

标签: html css flexbox

看这个小提琴:

https://jsfiddle.net/9hnj0b8v/3/

两个元素的唯一区别:

.label1
{
  display: inline-block;
}

.label2
{
  display: flex;
}

因此,除了一个标签设置为inline-block和一个标签设置为flex之外,这两个标签是相同的。为什么它们有不同的宽度?为什么一个超出了它的容器,另一个却没有?

3 个答案:

答案 0 :(得分:2)

您正在使用span设置display: inline-block元素的样式。默认情况下,块级元素是其父容器宽度的100%。当您用white-space: nowrap强制输入和跨度到同一行时,这将迫使跨度超出父容器的边界。

  

为什么它们的宽度不同?为什么一个超出了它的容器,另一个却没有?

使用display: flex可使子元素缩小以适合可用空间,因此span元素以其父元素的100%宽度开始,然后缩小以填充可用空间。

答案 1 :(得分:1)

这是因为white-space:nowrap

如果没有的话,这是预期的结果:

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  background: #f0f0f0;
}

span {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}

label {
  margin-top: 10px;
  /*white-space: nowrap;*/
}

.label1 {
  display: inline-block;
}

.label2 {
  display: flex;
}
<div>

  <label class=label1>
 <input type=checkbox>
 <span>
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to inline-block. For some reason,
  it overflows the containing div. But why?
</span>
</label>


</div>

请注意inline-block的宽度等于容器的宽度,因为其中有很多文本,并且文本会折断,所以就像有width:100%一样。然后,如果您添加white-space:nowrap,则只需禁用换行,并通过保持其宽度inline-block移到上方,就可以创建溢出 1

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  background: #f0f0f0;
}

span {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}

label {
  margin-top: 10px;
  white-space: nowrap;
}

.label1 {
  display: inline-block;
}

.label2 {
  display: flex;
}
<div>

  <label class=label1>
 <input type=checkbox>
 <span>
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to inline-block. For some reason,
  it overflows the containing div. But why?
</span>
</label>


</div>

对于flexbox而言,有所不同,因为自动换行由flex-wrap控制,默认情况下为nowrap。请注意,flexbox容器内的inline-block是无用的,因为当元素成为flex项时,它们会被阻塞

启用自动换行,您将获得与第一个示例类似的行为:

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  background: #f0f0f0;
}

span {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}

label {
  margin-top: 10px;
  /*white-space: nowrap;*/
}

.label1 {
  display: inline-block;
}

.label2 {
  display: flex;
  flex-wrap:wrap;
}
<div>

  <label class=label1>
 <input type=checkbox>
 <span>
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to inline-block. For some reason,
  it overflows the containing div. But why?
</span>
</label>

  <label class=label2>
 <input type=checkbox>
 <span>
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to flex. For some reason,
  it does not overflow the containing div. But why not?
</span>
</label>

</div>

现在添加空白的nowrap:

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  background: #f0f0f0;
}

span {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}

label {
  margin-top: 10px;
  white-space: nowrap;
}

.label1 {
  display: inline-block;
}

.label2 {
  display: flex;
  flex-wrap:wrap;
}
<div>

  <label class=label1>
 <input type=checkbox>
 <span>
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to inline-block. For some reason,
  it overflows the containing div. But why?
</span>
</label>

  <label class=label2>
 <input type=checkbox>
 <span>
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to flex. For some reason,
  it does not overflow the containing div. But why not?
</span>
</label>

</div>

flexbox不会发生任何事情,因为我们不再处理text和inline元素,而是关于flex项,因此空格在这里没有影响,因为它们是block元素,并且如上所述,包装由{{1 }}。

要注意的另一件事是,默认情况下,弹性项目将始终缩小以适合其父容器,这也解释了为什么即使设置了明确的宽度也不会出现过低的情况:

flex-wrap
div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  background: #f0f0f0;
}

span {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}

label {
  margin-top: 10px;
  white-space: nowrap;
}

.label1 {
  display: inline-block;
}

.label2 {
  display: flex;
}

但是,如果您禁用<div> <label class=label1> <input type=checkbox> <span> Here is a long description for the option that is set via the checkbox on the left. The label is set to inline-block. For some reason, it overflows the containing div. But why? </span> </label> <label class=label2> <input type=checkbox> <span style="width:200px;"> Here is a long description for the option that is set via the checkbox on the left. The label is set to flex. For some reason, it does not overflow the containing div. But why not? </span> </label> </div>,则可能会发生溢出:

shrink
div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  background: #f0f0f0;
}

span {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}

label {
  margin-top: 10px;
  white-space: nowrap;
}

.label1 {
  display: inline-block;
}

.label2 {
  display: flex;
}

如果没有明确的宽度,您将拥有以下内容:

<div>

  <label class=label1>
 <input type=checkbox>
 <span>
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to inline-block. For some reason,
  it overflows the containing div. But why?
</span>
</label>

  <label class=label2>
 <input type=checkbox>
 <span style="width:200px;flex-shrink:0">
  Here is a long description for the option that is set via the checkbox
  on the left. The label is set to flex. For some reason,
  it does not overflow the containing div. But why not?
</span>
</label>

</div>
div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  background: #f0f0f0;
}

span {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}

label {
  margin-top: 10px;
  white-space: nowrap;
}

.label1 {
  display: inline-block;
}

.label2 {
  display: flex;
}


1 这是另一个示例,用于说明<div> <label class=label1> <input type=checkbox> <span> Here is a long description for the option that is set via the checkbox on the left. The label is set to inline-block. For some reason, it overflows the containing div. But why? </span> </label> <label class=label2> <input type=checkbox> <span style="flex-shrink:0"> Here is a long description for the option that is set via the checkbox on the left. The label is set to flex. For some reason, it does not overflow the containing div. But why not? </span> </label> </div>的效果以及它如何更改以前计算的元素的宽度:

white-space:nowrap
.box {
  width:200px;
  border:2px solid red;
}
.box span {
  border:2px solid green;
  white-space:normal;
  display:inline-block;
  vertical-align:top;
}

答案 2 :(得分:0)

我观察到的主要区别是,使用内联块,无论父div中有多少个元素,它都会用inline-block元素填充父div,但是display: flex会划分您父级div的宽度(或高度)以及您拥有的元素数。

此外,在您的小提琴中,您已经为跨度设置了inline-block,只需尝试删除它,您将以更直观的方式看到差异