Flexbox平均分配元素大小,不考虑内容

41

如何使每个正方形的大小相同???

JSBIN上预览问题 | JSBIN上查看问题代码

我正在使用flexbox创建网格布局。 大多数网格单元格没有内容,而有些网格单元格则具有内容。 当单元格具有内容时,它会使所有内容偏移。 我该如何确保所有单元格的大小均匀,而不考虑其内容?

未正确调整大小

HTML

我有三行,每行有三个单元格。 仅中心单元格的中心行包含子元素。

<div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div>
  <div></div>
  <div><span>contains span</span></div>
  <div></div>
</div>

<div>
  <div></div>
  <div></div>
  <div></div>
</div>

CSS

在 CSS 中,中心空间比其他正方形要大。

body, html {
  height: 100%;
}

body {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

body>div {
  display: flex;
}

body>div>div {
  border: solid 1px blue;
}

div {
  flex-grow: 1;
}

body>div:nth-child(2)>div:nth-child(2) {
  display: flex;
  align-items: center;
  justify-content: center;
}
4个回答

51

您正在使用 flex-grow: 1。这意味着 flex 项目的初始宽度将是其内容的宽度,然后可用空间将被平均分配。

然而,您希望 flex 项目具有相同的宽度,因此要忽略它们内容的宽度。您可以通过以下方式实现:

flex: 1;

此外,Flexbox将auto引入为min-width的初始值。在某些情况下,这可能会产生不同的宽度,因此为了安全起见,最好添加min-width: 0或将overflow设置为除visible之外的任何内容

body,
html {
  height: 100%;
}
body {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
body > div {
  display: flex;
}
body > div > div {
  border: solid 1px blue;
}
div {
  flex: 1;
  min-width: 0;
}
body > div:nth-child(2) > div:nth-child(2) {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div>
  <div></div>
  <div></div>
  <div></div>
</div>
<div>
  <div></div>
  <div><span>contains span</span></div>
  <div></div>
</div>
<div>
  <div></div>
  <div></div>
  <div></div>
</div>


2
这是一个很好的解决方案,它能够工作是因为 flexflex-growflex-shrinkflex-basis 的缩写。它们的默认值分别为 0、1 和 auto。所以长手写法将会是:flex-grow: 1; flex-shrink: 1; flex-basis: 0;。请注意,flex-basis 是 0,而不是默认的 auto,因为如果您使用单个数字值设置 flex,则默认值实际上类似于 1 0(与省略 flex-basis 相同)。建议使用简写版本。 - Patrick
1
我曾经遇到一个问题,即可以调整 flexbox 的大小以使其增长,但一旦 flexbox 增长后,它就无法再次缩小。min-width: 0; 对我解决了所有问题。谢谢! - phlaxyr

23

您应该使用flex-basis来指定弹性项目的初始长度。

body, html {
  height: 100%;
}

body {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

body>div {
  display: flex;
}

body>div>div {
  border: solid 1px blue;
}

div {
  flex-grow: 1;
   flex-basis: 80px; /*set the initial length*/
}

body>div:nth-child(2)>div:nth-child(2) {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div>
  <div></div>
  <div><span>contains span asdsa asd asd asd asdsad ads asd sad</span></div>
  <div></div>
</div>

<div>
  <div></div>
  <div></div>
  <div></div>
</div>


3
为什么是80像素?当宽度取决于浏览器大小时,你如何知道需要设置80像素? - Tabbyofjudah
它可以是百分比,不一定是像素,但我只是举了一个例子。 - KAD
9
如果你只想均匀分布,请将 flex-basis: 0 设置为值。 - Icycool
1
flex-basis: 0 在我看来是解决这个问题的关键。谢谢 @Icycool。 - NubSteel

1

只需要设置 33% 的 flex-basis 属性即可。

  body>div>div {
      border: solid 1px blue;
      flex: 0 0 33%;
    }

body, html {
  height: 100%;
}

body {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

body>div {
  display: flex;
}

body>div>div {
  border: solid 1px blue;
  flex: 0 0 33%;
}

div {
  flex-grow: 1;
}

body>div:nth-child(2)>div:nth-child(2) {
  display: flex;
  align-items: center;
  justify-content: center;
}
   <div>
      <div></div>
      <div><span>contains span</span></div>
      <div></div>
    </div>
   <div>
      <div></div>
      <div></div>
      <div></div>
    </div>
      
   <div>
      <div></div>
      <div></div>
      <div></div>
    </div>
      
      


0

答案是在子元素上使用flex: 1 0 0

当前答案的问题在于它们要么没有将flex-basis明确设置为0,要么依赖于固定或百分比宽度,这假设您知道有多少列。在某些情况下,您可能具有可变数量的列,并仍希望在子元素之间均匀分配可用空间。

这是flex-grow: 1;flex-shrink: 0;flex-basis: 0;的速记。 通过将flex-basis设置为0,您正在要求浏览器在计算如何分配间距时不考虑元素的自然宽度与flex-grow: 1;

请参见MDN解释https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax

variable columns, equally distributed space

这是包含3列和4列示例的代码

<div class="flex">
    <div></div>
    <div></div>
    <div></div>
</div>

<div class="flex">
    <div></div>
    <div><span>contains span</span></div>
    <div></div>
</div>

<div class="flex">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>

<div class="flex">
    <div></div>
    <div><span>contains span</span></div>
    <div></div>
    <div></div>
</div>

<style lang="text/css">
.flex {
    display: flex;
    justify-content: center;
    gap: 3px;
    margin-bottom: 3px;
    background: rgba(0,0,0,0.15);
}
.flex > div {
    flex: 1 0 0;
    background: rgba(0,0,0,0.15);
    padding: 20px;
}
</style>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接