在嵌套容器中时,如何使flexbox项目正确收缩? [英] How to make flexbox items shrink correctly when in a nested container?

查看:76
本文介绍了在嵌套容器中时,如何使flexbox项目正确收缩?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If I set up a nested flexbox container like so:

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

...,然后将grow2的宽度设置为比container1宽 ,然后grow2溢出container1.

...and then set the width of grow2 such that it is wider than container1 then grow2 overflows container1.

我相信这不会 发生,因为当flex元素大于flex容器时,它们应该收缩.

I believe this should not happen since flex elements are supposed to shrink when they are larger than the flex container.

如果我设置了grow2的 flex-basis ,那么这将按预期工作.

If I set the flex-basis of grow2 then this works as expected.

请参见以下示例进行演示:

Please see the following example for a demo:

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

请为此使用Chrome或Firefox

此外,我读到flexbox规范说宽度和flex-basis应该具有明显不同的效果(当使用水平布局时).

Furthermore, I read that the flexbox spec says that width and flex-basis should have the same effect (when using horizontal layouts) which they clearly don't.

现在,我可以只使用flex-basis而不是width,但是... Edge对flex-basis和width都执行相同的操作,并且它以错误"的方式进行操作. IE11也做错了(尽管似乎有多个flexbox错误). 请使用Edge查看演示.

Now I could just use flex-basis instead of width, but... Edge does the same thing for both flex-basis and width, and it does it in the "wrong" way. IE11 does it wrong also (although that appears to have multiple flexbox bugs). Please check out the demo with Edge.

那么这应该如何工作?

So how is this supposed to work?

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

Are there bugs in all browsers?

实际上,flex-basis是否应该与宽度不同?

Is flex-basis actually supposed to be different from width (in simple horizontal layouts)?

还是Edge是正确的,宽度和弹性基础都应该溢出父容器?

Or is Edge correct and both width and flex-basis are supposed to overflow the parent container?

最后,有没有一种解决方法可以解决Edge(甚至IE11)的溢出问题?

Finally, is there a workaround that can fix the overflow for Edge (and even 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-basiswidthflex-growflex有关的问题.完全不同.

The Problem

As far as the spec is concerned, this isn't an issue pertaining to flex-basis, width, flex-grow or flex. It's something entirely different.

4.5.隐含的最小伸缩尺寸 项目

4.5. Implied Minimum Size of Flex Items

要为弹性商品提供更合理的默认最小尺寸,此 规范引入了新的auto值作为的初始值 CSS 2.1中定义的min-widthmin-height属性.

To provide a more reasonable default minimum size for flex items, this specification introduces a new auto value as the initial value of the min-width and min-height properties defined in CSS 2.1.

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

In other words, a flex item, by default, cannot be smaller than the length of its content (essentially, the longest word or fixed-size element).

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

The item cannot stay within its container (or even render a scroll bar or ellipsis), because its content is not permitted to overflow. The content simply expands the item. This behavior applies to fixed-sizing, as well (such as the flex-basis: 400px in your code).

同样,初始设置为:

  • min-width: auto,沿行方向
  • min-height: auto,在列方向
  • min-width: auto, in row-direction
  • min-height: auto, in column-direction

有关更完整的说明,请参见这篇文章:

For a more complete explanation see this post:

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

The standard solution to this problem is simple: override the default.

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

In your code, add min-width: 0 to .grow1.

这解决了Chrome,Safari,FF和Edge中的问题.

That solves the problem in Chrome, Safari, FF and 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中,与规范指南相反,flex min-width/min-height默认值已经是0,但是flex项目仍然存在.

In IE11, contrary to spec guidance, the flex min-width / min-height default values are already 0, yet the flex item still breaks out.

默认值为0,因为首次发布flexbox规范时,min-*属性没有偏离

The defaults are 0 because when the flexbox spec was first released, the min-* properties did not deviate from the CSS 2.1 initial values, which are 0.

稍后,在浏览器完成其实现之后,flex min-*值将更新为auto. Chrome,Safari,FF和Edge进行了更新. IE11没有.

Later, after browsers had completed their implementations, the flex min-* values were updated to auto. Chrome, Safari, FF and Edge made the update. IE11 did not.

在IE11中出现flex项的原因与另一个问题有关:浏览器希望在容器上显示明确的宽度

The reason the flex items break out in IE11 relates to another issue: the browser wants an explicit width on the container

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

In your code, add flex-basis: 100% to .grow1.

此处有更多详细信息:

  • Why IE11 doesn't wrap the text in flexbox?
  • flexbox flex-basis: 0px in Chrome

.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默认值.

Evidence appears to exist (in this question and other examples I've seen) that Webkit-based browsers are no longer honoring the auto default defined in the spec.

此外,对auto标准的遵守情况可能会根据用于确定大小的属性而有所不同:flex-basiswidth/height

Moreover, the adherence to the auto standard may vary based on which property is used for sizing: flex-basis vs. width / height

如以下博文所述,这些属性应以相同的方式呈现.

As discussed in the following post, these properties should render the same way.

这篇关于在嵌套容器中时,如何使flexbox项目正确收缩?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆