如何使弹性盒项目在嵌套容器中正确收缩?

2023-11-27

如果我像这样设置一个嵌套的弹性盒容器:

<div class="container1">
  <div class="grow1">
    <div class="container2">
      <div class="grow2"></div>
    </div>
  </div>
</div>

...然后设置width的grow2使得它是wider比container1然后grow2溢出container1。

我相信这应该not发生这种情况是因为当 Flex 元素大于 Flex 容器时,它们应该会收缩。

如果我设置弹性基础的grow2 那么这将按预期工作。

请参阅以下演示示例:

https://jsfiddle.net/chris00/ot1gjjtk/20/

为此,请使用 Chrome 或 Firefox

此外,我读到 Flexbox 规范说 width 和 flex-basis 应该具有相同的效果(当使用水平布局时),但它们显然没有。

现在我可以使用 flex-basis 而不是 width,但是... Edge 对 flex-basis 和 width 做了同样的事情,而且是以“错误”的方式完成的。 IE11 也做错了(尽管这似乎有多个 Flexbox 错误)。请使用 Edge 查看演示。

那么这应该如何运作呢?

所有浏览器都存在错误吗?

flex-basis 实际上应该与宽度不同(在简单的水平布局中)吗?

或者 Edge 是否正确并且 width 和 flex-basis 都应该溢出父容器?

最后,是否有解决方法可以修复 Edge(甚至 IE11)的溢出问题?

.container1 {
  margin-top: 10px;
  display: flex;
  width: 200px;
  height: 50px;
  background-color: red;
}

.grow1 {
  flex-grow: 1;
  height: 40px;
  background-color: green;
}

.container2 {
  display: flex;
  height: 30px;
  background-color: yellow;
}

.grow2a {
  flex-grow: 1;
  flex-basis: 400px;
  height: 20px;
  background-color: turquoise;
}

.grow2b {
  flex-grow: 1;
  width: 400px;
  height: 20px;
  background-color: turquoise;
}
<div class="container1">
  <div class="grow1">
    <div class="container2">
      <div class="grow2a">Working (flex-basis)</div>
    </div>
  </div>
</div>

<div class="container1">
  <div class="grow1">
    <div class="container2">
      <div class="grow2b">Not working (width)</div>
    </div>
  </div>
</div>

问题

就规范而言,这不是一个与flex-basis, width, flex-grow or flex。这是完全不同的东西。

4.5. Flex 的隐含最小尺寸 项目

为了为弹性项目提供更合理的默认最小尺寸,这 规范引入了新的auto值作为初始值 这min-width and min-heightCSS 2.1 中定义的属性。

换句话说,默认情况下,弹性项目不能小于其内容的长度(本质上是最长的单词或固定大小的元素)。

该项目不能保留在其容器内(甚至呈现滚动条或省略号),因为其内容不允许溢出。内容只是扩展了项目。此行为也适用于固定大小(例如flex-basis: 400px在你的代码中)。

同样,初始设置是:

  • min-width: auto,在行方向
  • min-height: auto,在列方向

更完整的解释请参阅这篇文章:

  • 为什么弹性项目不会缩小到超过内容大小?

适用于 Chrome、Safari、Firefox 和 Edge 的解决方案

此问题的标准解决方案很简单:覆盖默认值。

在您的代码中,添加min-width: 0 to .grow1.

这解决了 Chrome、Safari、FF 和 Edge 中的问题。

.container1 {
  margin-top: 10px;
  display: flex;
  width: 200px;
  height: 50px;
  background-color: red;
}

.grow1 {
  flex-grow: 1;
  height: 40px;
  background-color: green;
  min-width: 0; /* NEW */
}

.container2 {
  display: flex;
  height: 30px;
  background-color: yellow;
}

.grow2a {
  flex-grow: 1;
  flex-basis: 400px;
  height: 20px;
  background-color: turquoise;
}

.grow2b {
  flex-grow: 1;
  width: 400px;
  height: 20px;
  background-color: turquoise;
}
<div class="container1">
  <div class="grow1">
    <div class="container2">
      <div class="grow2a">Working (flex-basis)</div>
    </div>
  </div>
</div>

<div class="container1">
  <div class="grow1">
    <div class="container2">
      <div class="grow2b">Not working (width)</div>
    </div>
  </div>
</div>

修改后的小提琴 1


IE11解决方案

在 IE11 中,与规范指导相反,flexmin-width / min-height默认值已经是0,但弹性项目仍然破裂。

默认值是0因为当 Flexbox 规范首次发布时,min-*属性没有偏离CSS 2.1 初始值, 哪个是0.

后来,在浏览器完成其实现之后,flexmin-*值更新为auto。 Chrome、Safari、FF 和 Edge 进行了更新。 IE11没有。

Flex 项目在 IE11 中崩溃的原因与另一个问题有关:浏览器希望容器有明确的宽度

在您的代码中,添加flex-basis: 100% to .grow1.

更多详细信息请参见此处:

  • 为什么 IE11 不将文本换行到 Flexbox 中?
  • flexbox flex-basis: Chrome 中的 0px

.container1 {
  margin-top: 10px;
  display: flex;
  width: 200px;
  height: 50px;
  background-color: red;
}

.grow1 {
  flex-grow: 1;
  height: 40px;
  background-color: green;
  flex-basis: 100%; /* NEW */
}

.container2 {
  display: flex;
  height: 30px;
  background-color: yellow;
}

.grow2a {
  flex-grow: 1;
  flex-basis: 400px;
  height: 20px;
  background-color: turquoise;
}

.grow2b {
  flex-grow: 1;
  width: 400px;
  height: 20px;
  background-color: turquoise;
}
<div class="container1">
  <div class="grow1">
    <div class="container2">
      <div class="grow2a">Working (flex-basis)</div>
    </div>
  </div>
</div>

<div class="container1">
  <div class="grow1">
    <div class="container2">
      <div class="grow2b">Not working (width)</div>
    </div>
  </div>
</div>

修改后的小提琴 2 (IE11)


更多浏览器差异

有证据表明(在这个问题和我见过的其他例子中)基于 Webkit 的浏览器不再遵循auto规范中定义的默认值。

此外,坚持auto标准可能会根据用于调整大小的属性而有所不同:flex-basis vs. width / height

正如下面的文章中所讨论的,这些属性应该以相同的方式呈现。

  • flex-basis 和 width 有什么区别?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使弹性盒项目在嵌套容器中正确收缩? 的相关文章

随机推荐