使用 Flexbox 填充最后一行剩余空间

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

Chris Albrecht 在 StackOverflow 上发布了一个关于网格的问题。 基本上:假设您有一个具有未知数量子元素的元素。 每个子元素占据父元素宽度的一定百分比,从而形成相等的行,例如四个列时每个子元素宽度为 25%,三个列时每个子元素宽度为 33.33% 等。 目标是均匀地填充此“网格”的空间。 子元素数量未知,因此假设您使用 25% 的宽度,并且有 7 个子元素,则第一行有 4 个,第二行有 3 个。 Chris 需要这最后的 3 个子元素调整宽度以填充空间,而不是留下间隙。

Flexbox 正好可以解决这个问题,否则可能需要使用 JavaScript 干预。

解决方案本质上是使子元素能够使用 flex-wrap 换行,然后使用 flex-grow 填充空间。

.grid {
  display: flex;
  flex-wrap: wrap;
}

.grid-item {
  flex-grow: 1;
  min-width: 25%;
}

当每个网格项为红色并用边框分隔时,这是一个直观的示例

通过在不同的 @media 查询断点调整最小宽度,您可以很容易地使其响应式

.grid-item {
  flex-grow: 1;
  min-width: 25%;
}
@media (max-width: 1200px) {
  .grid-item {
    min-width: 33.33%; 
  }
}

这是该演示

如果您不喜欢使用 Flexbox 因为它尚未准备好使用,那么此示例适合您。 flex-wrap 在 Firefox 中一直到 最近 才出现,并且尚未进入稳定版,因此对于 Chris 来说可能还不是一个非常实用的解决方案。 但请记住,Firefox 会自动更新,因此当 28 版发布时,每个人都会很快获得它。 我仍然乐观地认为,Flexbox 在一年左右的时间内将成为新网站上一种相当标准的布局机制。

如果您只需要 Flexbox 用于单向内容,则可以回退到 display: table,如果您指的是通过某种精确度来复制布局的话。 如果您需要换行,则可以使用内联块。 您可以使用以下方法测试 Flexbox 换行支持

@supports not (flex-wrap: wrap) {

}

并且可能回退到 inline-block它们之间没有空格)如果您这样做,以下是如何在需要时使用 JavaScript 调整最后一行

var leftovers = $(".child").removeAttr("style").length % 4;
  
if (leftovers > 0) {
  var newWidth = 100 / leftovers;
  var fromHere = $(".child").length - leftovers + 1;
  $(".child:nth-child(n+" + fromHere + ")").css("width", newWidth + "%");
}

请注意其中的硬编码 4,它假设子元素宽度为 25%。 您可以更复杂一些并检测它。 我将把它留给您。 我使用一些 :nth-child 技巧 选择了最后几个落后的子元素(由模数 (%) 运算符确定)。 不过,这是一个演示

请记住,这里有一篇关于所有 Flexbox 属性的完整指南 此处