Chrome不会根据子元素的内容扩展flex容器大小

11

我需要将几个盒子并排显示。每个盒子都有不同数量的子项。父元素应根据子项占用的空间进行扩展。子项必须具有固定宽度。我正在使用flexbox进行布局。它应该像这样:

enter image description here

我写了一个 Plunkr 来进行示范。

问题:Chrome浏览器在子元素占用更多空间时不会扩展父元素。子项显示在父项边界之外,并出现在相邻的父项中,导致混乱:

enter image description here

具有讽刺意味的是,如果您在IE 11或Edge中打开Plunkr,则可以正常工作。

我做错了什么?

这是一个代码片段:

body {
  display: flex;
  overflow: scroll;
}

.parent {
  border: 1px solid grey;
  padding: 0 20px;
  display: flex;
  flex-direction: column;
}

.items {
  display: flex;
}

.items span {
  flex-basis: 25px;
  flex-shrink: 0;
}
<div class="parent">
  <h4>Parent 1</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 2</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 3</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 4</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 5</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 6</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>


使用宽度代替 flex-basis 可以起作用。 - inarilo
这是在嵌套的 flex 容器中发生的已知 bug。请参见重复问题的顶部答案中的“浏览器错误”部分。 - Michael Benjamin
3个回答

13

看起来这是Chrome的一个bug。

在这段代码中:

.items span {
  flex-basis: 25px;
  flex-shrink: 0;
}

... Chrome没有遵守固定的25像素宽度。或者说,容器没有识别到这个空间。看起来容器在所有项目计算考虑之前就被调整大小了。

简单的解决方法是使用width而不是flex-basis

.items span {
    flex-shrink: 0;
    width: 25px;
 }

修正后的演示


更新

错误报告

当调整嵌套的flex容器大小时,会忽略flex-basis属性。

"这是我们存在的一个错误的结果,也可能与不幸的规范结果结合在一起..."

"当外部flexbox找到内部flexbox的所需大小时,它会请求其max-content大小(请参见LayoutFlexibleBox :: computeInnerFlexBaseSizeForChild)。但在此时出现了错误,在计算max-content大小时没有考虑flex-basis属性,只考虑width属性/实际内容。这就是为什么添加显式宽度可以解决该错误的原因。"


2
那么Firefox也遭受了同样的错误 :) - Asons
1
是的,这种情况发生在Chrome、Firebox和Safari中...请注意:我认为这个错误可能并不总是发生,两个相同的元素具有相同的样式可能最终看起来不同。例如,在Chrome开发工具上修改样式后,我得到了一个好看的元素,但是当将其样式和内容复制到实际源代码时,错误就出现了。即使下载正确的源代码并在新标签页中打开,也会显示不正确。 - raquelhortab

2
尝试使用inline-flex替换flex,同时注释掉一些不需要的flex样式,请参考此处。

/* Styles go here */
body {
  /* display: flex; */
  overflow: scroll;
}

.parent {
  border: 1px solid grey;
  padding: 0 20px;
  display: inline-flex;
  flex-direction: column;
}

.items {
  /* display: flex; */
}

.items span {
  flex-basis: 25px;
  flex-shrink: 0;
}
<div class="parent">
  <h4>Parent 1</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 2</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 3</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 4</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>
<div class="parent">
  <h4>Parent 5</h4>
  <div class="items">
    <span>i1</span>
    <span>i2</span>
    <span>i3</span>
    <span>i4</span>
    <span>i5</span>
  </div>
</div>


CSS不支持//单行注释,只支持多行/* */注释。我编辑了你的答案以修复CSS问题 :) - Vadim Ovchinnikov
这也会改变所期望的布局。body的内容不应该换行。 - Vadim Ovchinnikov

-1
请看一下:
使用 box-sizing: border-box; 来设置父元素,并使用 width 来保持每个元素的宽度。

https://plnkr.co/edit/3p8PwmLtHYozEFveRvTX

/* Styles go here */

body {
  display: flex;
  overflow: scroll;
}

.parent {
  border: 1px solid grey;
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  box-sizing : border-box;
}

.items {
  display: flex;
}

.items span {
  width: 25px;
}

HTML:

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <script src="script.js"></script>
</head>

<body>
  <div class="parent">
    <h4>Parent 1</h4>
    <div class="items">
      <span>i1</span>
      <span>i2</span>
      <span>i3</span>
      <span>i4</span>
      <span>i5</span>
      <span>i1</span>
      <span>i2</span>
      <span>i3</span>
      <span>i4</span>
      <span>i5</span>
    </div>
  </div>
  <div class="parent">
    <h4>Parent 2</h4>
    <div class="items">
      <span>i1</span>
      <span>i2</span>
      <span>i3</span>
      <span>i4</span>
      <span>i5</span>
    </div>
  </div>
  <div class="parent">
    <h4>Parent 3</h4>
    <div class="items">
      <span>i1</span>
      <span>i2</span>
      <span>i3</span>
      <span>i4</span>
      <span>i5</span>
    </div>
  </div>
  <div class="parent">
    <h4>Parent 4</h4>
    <div class="items">
      <span>i1</span>
      <span>i2</span>
      <span>i3</span>
      <span>i4</span>
      <span>i5</span>
    </div>
  </div>
  <div class="parent">
    <h4>Parent 5</h4>
    <div class="items">
      <span>i1</span>
      <span>i2</span>
      <span>i3</span>
      <span>i4</span>
      <span>i5</span>
    </div>
  </div>
  <div class="parent">
    <h4>Parent 6</h4>
    <div class="items">
      <span>i1</span>
      <span>i2</span>
      <span>i3</span>
      <span>i4</span>
      <span>i5</span>
    </div>
  </div>
</body>

</html>

是的!这个方法可行!你能否更新你的答案,说明做了哪些更改(例如将 box-sizing: border-box; 应用于 flex 父元素并从子元素中删除 flex-shrink: 0;)?这样其他人就可以更容易地看到修复方式,而不必逐行比较代码。 - fikkatra
仔细看,它打破了每个项目固定的25像素宽度...有什么线索吗? - fikkatra
.items span { width : 25px; }使用width:25px可以保持每个项目的宽度。我会更新答案,说明问题已解决。 - Younis Ar M
2
box-sizing与此无关。 - Asons

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