很久以前(大约2013年),我写了一个jQuery插件来计算等高的列。它确保了一个有三列的行的非常特殊的情况下,无论内容的长度如何,都能保持内容框的等高。当时主流的布局方法--浮动--并不能处理这个问题。
Flexbox解决方案#
当Flexbox出现时,这就成为了可能:
.flexbox {
display: flex;
}
令人惊讶的是!默认情况下,直接子节点排成一排,并应用了 "拉伸",因此它们的高度相等🙌。
但是,当你添加两个.column divs作为子代时,......列的内容又出现了不平等的情况😔。
解决的办法是:
.flexbox {
display: flex;
// Ensure content elements fill up the .column
.element {
height: 100%;
}
}
现在,这些列将出现等高,并随着.element 的内容而增长。
网格解决方案#
使用网格,我们会遇到类似的行为:
.grid {
display: grid;
// Essentially switch the default axis
grid-auto-flow: column;
}
与flexbox类似,直接的子节点将是等高的,但它们的子节点需要像flexbox方案那样添加高度定义:
.grid {
display: grid;
grid-auto-flow: column;
// Ensure content elements fill up the .column
.element {
height: 100%;
}
}
哪个更好?#
对于纯粹解决等高元素的问题,flexbox的优势在于默认轴线可以立即启用并排的列,而grid则需要明确设置。然而,元素本身不会是等宽的(这可能是一个优势,取决于内容的类型,例如导航链接)。
网格的优势在于,如果需要的话,元素本身就是等宽的。另一个优点是,当你不想要自动流动,而是想要定义一个每 "行 "的最大列数。在这种情况下,网格布局可以很容易地处理分配列的数学问题,而灵活的解决方案则需要定义计算来限制列的数量。
更新我们的.grid ,以处理定义每行最大3个.column ,就这么简单:
&.col-3 {
gap: $col_gap;
grid-template-columns: repeat(3, 1fr);
}
而Flexbox的一个(非常基本的)选项是:
$col_gap: 1rem;
.flexbox.col-3 {
// Explicitly needs to be defined to wrap
// overflow items to the next virtual row
flex-wrap: wrap;
.column {
// "hack" for no gap property
margin: $col_gap/2;
// define calculation for browser to use on the width
max-width: calc((100% / 3) - #{$col_gap});
}
}
你还需要考虑这些解决方案如何进行响应式处理,但这有点超出了本文的范围 :)