用Flexbox和Grid来计算等高的改进(附实例)

795 阅读2分钟

很久以前(大约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});
  }
}

你还需要考虑这些解决方案如何进行响应式处理,但这有点超出了本文的范围 :)