最后一行的 flex-grow 与 flex-wrap 不一致

Inconsistent flex-grow in last row with flex-wrap

请看我的非常简单的 flex 布局示例:

尽管所有的规则集,最后一行的项目有不同的宽度?当 flex-grow 说所有项目都将平等缩放时,这怎么可能?

引自http://www.w3schools.com/cssref/css3_pr_flex-grow.asp

The flex-grow property specifies how much the item will grow relative to the rest of the flexible items inside the same container.

太棒了,但我在最后一行的项目比其他项目增长了一点。有什么想法吗?

flex {
  display: flex;
  flex-wrap: wrap;
}
item {
  flex: 1 0 4rem;
  height: 4rem;
  margin: 0.5rem;
  border: 1px solid lightblue;
}
<flex>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
</flex>

弹性grow and shrink factors are basically used to Resolve Flexible Lengths。但这对于每条弹性线(行或列)都是独立发生的。

To resolve the flexible lengths of the items within a flex line: [...]

  • If using the flex grow factor

    Find the ratio of the item’s flex grow factor to the sum of the flex grow factors of all unfrozen items on the line. Set the item’s target main size to its flex base size plus a fraction of the remaining free space proportional to the ratio.

  • If using the flex shrink factor

    For every unfrozen item on the line, multiply its flex shrink factor by its inner flex base size, and note this as its scaled flex shrink factor. Find the ratio of the item’s scaled flex shrink factor to the sum of the scaled flex shrink factors of all unfrozen items on the line. Set the item’s target main size to its flex base size minus a fraction of the absolute value of the remaining free space proportional to the ratio.

CSS 工作组已经意识到这个问题,plans to introduce some way to fix it in Flexbox Level 2

Solve the “items on the last line get way too big when you're flexing” problem. More generally, “make items have a consistent flexed size, regardless of how much extra space is on each line”.

  • Possible solution - fill out the last line with “phantom copies” of the last item, flex with them in, then remove them.
  • Possible solution - calculate minimum values of 1fr and alignment free space across the entire flexbox (instead of per-line) and use that.

添加 css 很容易,就像:

.flexlast::after{ //here use after add a element
    content: "  ";
    flex: 100;    //100 just big enough, maybe 50 is ok too.
}

flex {
  display: flex;
  flex-wrap: wrap;
}
item {
  flex: 1 0 4rem;
  height: 4rem;
  margin: 0.5rem;
  border: 1px solid lightblue;
}
flex::after{
    content: "  ";
    flex: 100;     
}
<flex>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
  <item></item>
</flex>