【问题标题】:Can flexbox handle varying sizes of columns but consistent row height?flexbox 可以处理不同大小但行高一致的列吗?
【发布时间】:2018-07-07 16:34:18
【问题描述】:

我只是在学习 flexbox 的工作原理,想构建一个非常粗略的原型,看看 flexbox 是否可以处理这种布局。

我基本上想看看 flexbox 是否可以支持具有不同宽度和高度但行高一致的 4 列表。

我不确定我是否很好地解释了布局,所以这里是我所追求的快速草图:

所以我关心的是:如果我使用 HTML 表格进行此操作,无论特定列有多少高度,每一行都将是一致的。

【问题讨论】:

  • 到目前为止你尝试了什么?怎么没有像你预期的那样工作?
  • 这只是一个学习练习,还是一个真正的项目?因为对我来说,这看起来像(并且应该表示为)一张桌子......
  • @Beejamin 这是真正的不学习,但我正在学习 flex 并阅读有关它将如何彻底改变我们所知道的世界的信息,所以我认为我应该使用它。
  • 很多人声称 flexbox 将彻底改变我们所知道的网络。他们在夸大其词。 Flexbox 并不是人们所说的通用布局解决方案。 Flexbox 恰好是大多数布局应该使用的解决方案,因为它存在 15 年之久,但它只是一个这样的解决方案。它不是表格或内联布局的替代品,从来都不是。 (奇怪的是,我刚刚编辑了an answer of mine,说是在你发布这个问题之后但在我看到它之前。)
  • 至于标题,“flexbox 可以处理不同大小的列,但行高一致吗?”答案是“这就是 flexbox all 的意义所在!”但是您的草图表明您的问题比标题所暗示的要多。

标签: html css flexbox


【解决方案1】:

我基本上想看看 flexbox 是否可以支持 4 列表 不同的宽度和高度,但具有一致的行高。

简单地说,Flexbox 与 HTML Table 共享的一个很好的特性是,同一行上的 flex 项目可以具有相同的高度,由 align-items property 控制。它的默认值是stretch,这样会使一行中的项目高度相等。

.flex-container {
  display: flex;
  flex-wrap: wrap;                    /*  allow items to wrap  */
  justify-content: space-between;     /*  vertical  */
  align-items: stretch;               /*  horizontal, is default
                                          and can be omitted  */
}

.flex-item {
  flex-basis: 23%;                    /*  give each item a width  */
  background-color: #ccc;
  padding: 10px;
  box-sizing: border-box;
}

.flex-item:nth-child(n+5) {
  margin-top: 10px;                   /*  from 5th item, add top margin  */
}
<div class="flex-container">
  <div class="flex-item">Left<br>high</div>
  <div class="flex-item">Middle/Left</div>
  <div class="flex-item">Middle/Right</div>
  <div class="flex-item">Right</div>
  
  <div class="flex-item">Left</div>
  <div class="flex-item">Middle/Left</div>
  <div class="flex-item">Middle/Right</div>
  <div class="flex-item">Right</div>
  
  <div class="flex-item">Left</div>
  <div class="flex-item">Middle/Left</div>
  <div class="flex-item">Middle/Right<br>higher<br>higher</div>
  <div class="flex-item">Right</div>
</div>

可能值得一提的是 Flexbox 不与 HTML Table 共享

  • 动态相等的列宽。

如果一个项目的内容比同一列中的其他项目更宽,其他项目不会将其宽度调整为等于最宽。

.flex-container {
  display: flex;
  flex-wrap: wrap;                    /*  allow items to wrap  */
  justify-content: space-between;     /*  vertical  */
  align-items: stretch;               /*  horizontal, is default
                                          and can be omitted  */
}

.flex-item {
  flex-basis: 23%;                    /*  give each item a width  */
  background-color: #ccc;
  padding: 10px;
  box-sizing: border-box;
}

.flex-item:nth-child(n+5) {
  margin-top: 10px;                   /*  from 5th item, add top margin  */
}
<div class="flex-container">
  <div class="flex-item">Left<br>high</div>
<div class="flex-item">Middle/Left&nbsp;-&nbsp;&nbsp;is&nbsp;wider</div>
  <div class="flex-item">Middle/Right</div>
  <div class="flex-item">Right</div>
  
  <div class="flex-item">Left</div>
  <div class="flex-item">Middle/Left</div>
  <div class="flex-item">Middle/Right</div>
  <div class="flex-item">Right</div>
  
  <div class="flex-item">Left</div>
  <div class="flex-item">Middle/Left</div>
  <div class="flex-item">Middle/Right<br>higher<br>higher</div>
  <div class="flex-item">Right</div>
</div>

通过防止 flex 项目缩小,并使它们小于其内容,可以强制等宽。

注意,overflow: hidden(或除visible 之外的任何值)与min-width: 0 具有相同的效果,因此在下面的示例中min-width 可以省略。

.flex-container {
  display: flex;
  flex-wrap: wrap;                    /*  allow items to wrap  */
  justify-content: space-between;     /*  vertical  */
  align-items: stretch;               /*  horizontal, is default
                                          and can be omitted  */
}

.flex-item {
  flex-basis: 23%;                    /*  give each item a width  */
  background-color: #ccc;
  padding: 10px;
  box-sizing: border-box;
  
  flex-shrink: 0;                     /*  prevent from "shrink to fit" */
  min-width: 0;                       /*  allow to shrink past content width  */
  overflow: hidden;                   /*  hide overflowed content  */
}

.flex-item:nth-child(n+5) {
  margin-top: 10px;                   /*  from 5th item, add top margin  */
}
<div class="flex-container">
  <div class="flex-item">Left<br>high</div>
<div class="flex-item">Middle/Left&nbsp;-&nbsp;&nbsp;is&nbsp;wider</div>
  <div class="flex-item">Middle/Right</div>
  <div class="flex-item">Right</div>
  
  <div class="flex-item">Left</div>
  <div class="flex-item">Middle/Left</div>
  <div class="flex-item">Middle/Right</div>
  <div class="flex-item">Right</div>
  
  <div class="flex-item">Left</div>
  <div class="flex-item">Middle/Left</div>
  <div class="flex-item">Middle/Right<br>higher<br>higher</div>
  <div class="flex-item">Right</div>
</div>

更合适的比较是 CSS Grid,它几乎可以做 HTML Table 可以做的所有事情,然后是一些 :)


这里是 Flexbox 和 CSS Grid 的两个很棒的指南:

【讨论】:

  • 具有讽刺意味的是,您无法在 HTML 表格中实现 CSS 网格布局,因为 CSS 网格布局需要一个网格容器元素,其所有子项都是网格项,而 HTML 表格则以table 元素,后跟 table-row 元素,然后是每行的 table-cell 元素。所以即使 display: grid 也不能完全替代 display: table。
  • @BoltClock 这就是为什么我说更合适的比较... :)
【解决方案2】:

一致的行高实际上是 flexbox 中的默认设置。

您无法获得equal height rows in a flex container,这意味着所有行共享相同的高度。为此,您可以使用CSS Grid layout

但是使用 flexbox,每一行本身可以在所有列中具有相同的高度。

body {
  display: flex;
  justify-content: center;
}

.container {
  display: flex;
  flex-wrap: wrap;
  width: 75%;
}

.box {
  flex: 1 0 20%; /* see note below */
  margin: 0 5px 5px 0;
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.2em;
}
<div class="container">
  <div class="box">GROUP 1</div>
  <div class="box">text text text text text text text text text text text text text text text text</div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box">GROUP 2</div>
  <div class="box"></div>
  <div class="box">text text text text text text text text</div>
  <div class="box"></div>
  <div class="box">GROUP 3</div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box">text text text text text text text texttext text text text text text text text</div>
  <div class="box">GROUP 4</div>
  <div class="box">text text text text text text text text</div>
  <div class="box"></div>
  <div class="box"></div>
</div>

jsFiddle demo

关于flex: 1 0 20%,基本概念如下:

  • 弹性容器设置为wrap

  • 1234563 /p>
  • 由于flex-grow 将占用行上的可用空间,flex-basis 只需大到足以强制执行换行。在这种情况下,使用flex-basis: 20%,有足够的空间放置边距,但没有足够的空间放置第五个项目。


更多信息:

【讨论】:

  • 在你的例子中,你如何保证每行有 3 4 列?我看不到“Group x” div 如何强制换行
  • @Blankman 在这个和我的回答中,它是集合flex-basis,这里是 20%。所以 4 个项目,每个 20% + 边距,不会在 100% 内为第 5 个腾出空间,因此它在 4 个之后换行。我使用了长手属性 flex-basis: 23%,这个答案使用了速记 flex: 1 0 20%,其中最后一个值为flex-basis
猜你喜欢
  • 2011-02-16
  • 2017-02-10
  • 2019-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-04
相关资源
最近更新 更多