flexbox 可以处理不同大小但行高一致的列吗?

Posted

技术标签:

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

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

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

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

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

【问题讨论】:

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

https://css-tricks.com/snippets/css/a-guide-to-flexbox/ https://css-tricks.com/snippets/css/complete-guide-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%,有足够的空间放置边距,但没有足够的空间放置第五个项目。


更多信息:

Equal height rows in a flex container Equal height rows in CSS Grid Layout

【讨论】:

在你的例子中,你如何保证每行有 3 4 列?我看不到“Group x” div 如何强制换行 @Blankman 在这个和我的回答中,它是集合flex-basis,这里是 20%。所以 4 个项目,每个 20% + 边距,不会在 100% 内为第 5 个腾出空间,因此它在 4 个之后换行。我使用了长手属性 flex-basis: 23%,这个答案使用了速记 flex: 1 0 20%,其中最后一个值为flex-basis

以上是关于flexbox 可以处理不同大小但行高一致的列吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 FlexBox(或其他 css),是不是可以在每行中有不同数量的相同大小的列(即不使用空 div)?

我们可以将数据从一个列复制到另一个具有不同数据类型的列吗?

窗口函数 LAG 可以引用正在计算哪个值的列吗?

我们可以展平 Hive 表中包含 Json 作为值的列吗?

我可以稍后在同一视图中使用在 SQL Server 视图中计算的列吗?

我可以使用 groupby 在 Pandas 数据框中创建每行是运行列表的列吗?