Html 为什么百分比宽度大小的弹性框项目不能正确增加具有未指定(即自动)宽度的包装表的宽度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34572022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 18:42:57  来源:igfitidea点击:

Why do percentage-width-sized flex box items not properly increase the width of a wrapping table that has an unspecified (i.e. auto) width?

htmlcssflexbox

提问by Hauke P.

Please take a look at this snippet:

请看一下这个片段:

table {
  background-color: yellow;
  box-shadow: inset 0 0 1px red;
  max-width: 100%;
  
  /* You would get similarly strange behavior with collapsing borders: */
  /* border-collapse: collapse; */
}

td {
  background-color: lightgreen;
  box-shadow: inset 0 0 1px blue;
  max-width: 100%;
}

.flex {
  max-width: 100%;
  display: flex;
  flex: 1;
  background-color: lightblue;
  box-shadow: inset 0 0 1px black;
  flex-wrap: wrap;
}

.box {
  width: 50%;
  background-color: cyan;
  border-radius: 9px;
  box-shadow: inset 0 0 1px red;
}
<table>
  <tr>
    <td>
      <div class="flex">
        <div class="box">
          123456789ABCDEFGHIJKL
        </div>
        <div class="box">
          meeedium
        </div>
        <div class="box">
          short
        </div>
      </div>
    </td>
  </tr>
</table>
(Here's a codepen if you want to play with it more easily: http://codepen.io/anon/pen/MKJmBM)(如果您想更轻松地使用它,这里有一个代码笔:http://codepen.io/anon/pen/MKJmBM )

Please note that the text in the upper left boxdoes not completely fit into it. (At least in Chrome it does not.) I was assuming that the wrapping table would try to "push" its width in order for its contents to completely fit into itself. So is this an implementation bug? Or an unspecified behavior? Or is my code simply flawed?

请注意,左上角的文字box并不完全适合其中。(至少在 Chrome 中它没有。)我假设包装表会尝试“推动”其宽度,以便其内容完全适合自身。那么这是一个实现错误吗?还是未指明的行为?或者我的代码只是有缺陷?

Can someone explain this behavior and provide a solution to fix it?

有人可以解释这种行为并提供解决方案吗?

(By the way... I ran into this strange behavior while experimenting with some initial solution sketches for this question: Using CSS, how to create a two-column grid with equal-width columns that are "only as narrow as required"?)

(顺便说一句......我在尝试针对这个问题的一些初始解决方案草图时遇到了这种奇怪的行为:使用 CSS,如何创建一个具有等宽列的两列网格,这些列“仅按要求窄”?)



Edit:The two "visual columns" should both have an equal width. Therefore solutions involving for example max-width: 50%;for .boxare not what I'm looking for. My question is really about the table: Why does it not increase its width so that all of its contents fit properly into itself?

编辑:两个“可视列”应该具有相等的宽度。因此,涉及例如max-width: 50%;for 的解决方案.box不是我正在寻找的。我的问题实际上是关于表格的:为什么它不增加它的宽度,以便它的所有内容都适合自己?

A solution for the problem should make sure that the table will not be "too wide": It should only be as wide as required so that the contents will just fit - but not a single subpixel wider.

该问题的解决方案应该确保表格不会“太宽”:它应该只与需要一样宽,以便内容刚好适合 - 但不能更宽一个子像素。

采纳答案by Oriol

This is explained in 9.2. Line Length Determination.

这在9.2 中有解释线长测定

  • First, the flex base size is determined for each item. This case it's complicated, because width: 50%depends on the available size. The spec says

    If the used flex basisis contentor depends on its available size, and the flex container is being sized under a min-content or max-content constraint (e.g. when performing automatic table layout[CSS21]), size the item under that constraint. The flex base sizeis the item's resulting main size.

    I'm not sure if that means the flex base size will be the min-content or max-content, because CSS tables use both. But since there are no wrap opportunities, both should be the same.

    So the flex base size will be the width of the text.

  • Then,

    Determine the main sizeof the flex container using the rules of the formatting context in which it participates.

    Then, the table and the flex container will be as wide as the sum of texts.

  • 首先,确定每个项目的 flex 基础尺寸。这种情况很复杂,因为width: 50%取决于可用大小。规范说

    如果使用的flex 基础content或取决于其可用大小,并且 flex 容器在 min-content 或 max-content 约束下调整大小(例如,在执行自动表格布局[CSS21] 时),则在该约束下调整项目的大小。该 柔性基座尺寸是该项目的产生主要尺寸

    我不确定这是否意味着 flex 基本大小将是 min-content 或 max-content,因为 CSS 表同时使用两者。但由于没有包装机会,两者应该是相同的。

    所以 flex 基本尺寸将是文本的宽度。

  • 然后,

    使用它参与的格式化上下文的规则确定flex 容器的主要大小

    然后,表格和 flex 容器将与文本总和一样宽。

Once the width of the flex container has been established, the percentages of the flex items can be resolved. But they won't affect the width of the flex container (nor the table).

一旦确定了 flex 容器的宽度,就可以解析 flex 项目的百分比。但它们不会影响 flex 容器(也不会影响表格)的宽度。

You can see this better in this snippet:

你可以在这个片段中更好地看到这一点:

.flex {
  display: flex;
  background-color: lightblue;
  box-shadow: inset 0 0 1px black;
  flex-wrap: wrap;
}
.box {
  width: 50%;
  background-color: cyan;
  border-radius: 9px;
  box-shadow: inset 0 0 1px red;
}
<table>
  <tr>
    <td>
      <div class="flex">
        <div class="">
          123456789ABCDEFGHIJKL
        </div>
        <div class="">
          meeedium
        </div>
        <div class="">
          short
        </div>
      </div>
    </td>
  </tr>
</table>
<table>
  <tr>
    <td>
      <div class="flex">
        <div class="box">
          123456789ABCDEFGHIJKL
        </div>
        <div class="box">
          meeedium
        </div>
        <div class="box">
          short
        </div>
      </div>
    </td>
  </tr>
</table>

Basically, what you want is make all flex items as wide as the widest one. I don't think there is a way to do that in CSS, but you can use JS.

基本上,您想要的是使所有 flex 项目与最宽的项目一样宽。我认为在 CSS 中没有办法做到这一点,但您可以使用 JS。

回答by Rene van der Lende

Actually, while I am not 100% sure about what you want, the solution seems to be close to my previous comment. Remove flex: 1from .flexand change width:50%in .boxto flex-basis: 50%.

实际上,虽然我不是 100% 确定您想要什么,但解决方案似乎与我之前的评论很接近。删除flex: 1.flex和变革width:50%.boxflex-basis: 50%

Oh, and while you're at it, add a space in the 123456789ABCDEFso it can actually wrap....

哦,当你在做的时候,在里面加一个空格,123456789ABCDEF这样它就可以真正包裹......

table {
  background-color: yellow;
  box-shadow: inset 0 0 1px red;
  max-width: 100%;
  
  /* You would get similarly strange behavior with collapsing borders: */
  /* border-collapse: collapse; */
}

td {
  background-color: lightgreen;
  box-shadow: inset 0 0 1px blue;
  max-width: 100%;
}

.flex {
  max-width: 100%;
  display: flex;
/* flex: 1;  REMOVE */
  background-color: lightblue;
  box-shadow: inset 0 0 1px black;
  flex-wrap: wrap;
}

.box {
  flex-basis: 50%; /* CHANGED from -> width: 50% */
  background-color: cyan;
  border-radius: 9px;
  box-shadow: inset 0 0 1px red;
}
<table>
  <tr>
    <td>
      <div class="flex">
        <div class="box">
          123456789 ABCDEFGHIJKL <!-- NOTICE THE SPACE!!!!-->
        </div>
        <div class="box">
          meeedium
        </div>
        <div class="box">
          short
        </div>
      </div>
    </td>
  </tr>
</table>

回答by Rich fiifi

Use min-width on the box. What are you trying to do exactly? why are you using tables? you could use normal floating divs for something like this and it wont face a lot of problem.

在框上使用 min-width 。你到底想做什么?你为什么使用表格?你可以使用普通的浮动 div 来做这样的事情,它不会遇到很多问题。

#container {
  
  width:50%;

  }

.box{
  max-width:49%;
  float:left;
  border:solid 3px #ccc;
 }


 .clearfix {
   clear:both;
   }
<div id="container">
  <div class="box">
  28432412341341234
  </div>
    <div class="box">
  second boxxxxx
  </div>
    <div class="box">
  third boxxxxxxxxx
  </div>
  <div class="clearfix">
    </div>
  
  </div>

回答by gmanou

The thing is that you need to define width in some way. There are two ways to do that.

问题是您需要以某种方式定义宽度。有两种方法可以做到这一点。

1) Width handler: Last outter element

1) 宽度处理器:最后一个外部元素

Adjust inner elements' width to outter elements' width with percentage values, thus the last element ( inner to outer ) that you define the width of, will be the width handler for all it's inner elements.

使用百分比值将内部元素的宽度调整为外部元素的宽度,因此您定义宽度的最后一个元素(从内部到外部)将成为所有内部元素的宽度处理程序。

2) Width handler: Content

2)宽度处理程序:内容

Adjust outter elements to the width of the content, leaving them widthless to wrap the content just like a sock would take the shape of your foot.

将外部元素调整为内容的宽度,使它们不具有宽度以包裹内容,就像袜子将采用您的脚的形状一样。

Anyway you should really consider changing your markup and make it tableless as @Rich fiifi said.

无论如何,您应该真正考虑更改您的标记并使其成为@Rich fiifi 所说的无表。