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 - is 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 - is 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
。
由于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)?