互联网上有很多很棒的 CSS 资源。但是,如果你只想要一个简单的布局,并且现在就需要,怎么办?

在本文中,我将描述 5 种最常见的网页布局,以及如何使用 Flexbox 和 Grid 构建它们。

如何运行

在 CodePen 上,每个布局下方都有一个完整 HTML 和 CSS 代码的链接。

请注意,我使用 SASS 来编写样式定义,因此如果你想在本地执行相同操作,请使用以下命令安装 SASS:

npm i sass -g

基本卡片模版

我使用上面的卡片作为网页布局的基础。它由垂直方向的三个元素组成,因此普通的 div 块就可以。但是,我稍后需要使中间的元素 - 文本段落 - 拉伸。

在这里 Flexbox 和 Grid 无缝地完成了这项工作。我更喜欢 Flexbox,因为它对我来说更直接。

获胜者:Flexbox

CodePen FlexboxCodePen Grid

现在让我们开始创建不同的布局。

#1 垂直且水平居中一张卡片

对于 Flexbox,我们需要一个水平居中的元素,以及垂直居中的另一个(子元素)。

项目的顺序由 flex-direction 定义的。元素如何在可用空间中定位自己是由元素上的 align-self 或其父元素上的 align-items 设置的。

对于 Grid,我们需要三列三行。然后我们将卡片放在中间的单元格中。

水平居中很容易。我们使用 grid-template-columns: auto 33% auto 定义三列及其大小,因为卡片应该和可见区域的 1/3 一样宽。

问题是,我们不知道垂直尺寸。我们希望顶行和底行占据网格无法实现的剩余空间。 卡片居中,但其高度取决于窗口的高度。

但是,我们可以通过在卡片周围添加额外的环绕元素,并使用 margin 将其居中,来解决此问题。

获胜者Flexbox

CodePen FlexboxCodePen Grid

#2 垂直且水平居中两张卡片

通常我们需要将多个元素居中。将两张卡片保持相同的高度,即使其中一张卡片包含更长的文本。

使用 Flexbox,我们需要将两张卡片包裹在另一个元素中,并使用它同时将两张卡片居中。

我们不能在这里使用 align-items,因为在这种情况下它适用于 Y 轴。我们需要用 justify-content: center 来定义 X 轴上的剩余空间应该如何分布。这样可以确保两张卡都水平居中。

如果我们省略 Grid 的可变高度问题,即使没有任何额外的包裹元素,我们也可以获得相同的结果。这次我们用 grid-template-columns: auto 33% 50px 33% auto 定义了五列网格,其余部分与前一个示例中的相同。

获胜者Flexbox

CodePen FlexboxCodePen Grid

#3 多张卡片具有相同的宽度和高度

这是博客、电子商务网站或通常显示某种列表的任何网站的另一个典型用例。我们希望卡片具有相同的宽度和高度。需要从列表中最大的元素推断高度。

这可以在 Flexbox 中使用 flex-wrap: wrap 来完成。如果元素的宽度超过每行的剩余空间,则元素将换行到下一行。但是,除非你明确定义,否则只在单行内保持相同的高度。

Grid 在这里展示了它的真正力量。可以使用 grid-auto-rows: 1fr 创建此布局,它在所有行上强制执行相同的高度。

获胜者Grid

CodePen FlexboxCodePen Grid

#4 垂直和水平居中交替文本和图像

在这个例子中,我们有带有 CTA 按钮的文本,另一侧有一个图像。两个组件都应垂直居中,因为它们的大小可能会有所不同。

这对 Flexbox 来说是小菜一碟。每一行都是一个 article 元素,分为两个包装容器,.img.content。它们是均匀尺寸分布所必需的(flex-basis: 50%)。

内部内容的垂直居中由 align-items: center 定义。

交替是通过在每个奇数文章上使用 flex-direction: row-reverse 反转 Flexbox 的方向来实现的。

Grid 也很好地处理了这个用例。我们不需要定义一个巨大的网格,而是为每个 article 定义一个。

它使用 align-items: center 定义垂直居中的同样宽的列。

交替是通过 grid-column 的切换值在单元格级别定义的。

获胜者:平手

CodePen FlexboxCodePen Grid

#5 带菜单的水平标题

要使用 Flexbox 实现这种设计,标题的两侧都需要由单个元素表示。

logo 和公司名称在左侧形成一个锚点 anchor,菜单是右侧的单个 nav 元素。Flexbox 使用 justify-content: space-between 来定位它们。

对于 Grid,我们需要两列——一列用于 logo,另一列用于菜单。该菜单是另一个使用 grid-template-columns: repeat(4, minmax(0, 1fr)) 均匀分布列大小的网格。

这里的问题是,如果我们想在菜单中添加另一个项目,我们还需要调整 CSS。

获胜者Flexbox

CodePen FlexboxCodePen Grid

获胜者是......

最终的比分是 5:2,Flexbox 领先,但这并不意味着它成为最终的 CSS 赢家。在某些情况下,你需要使用其中一种,有时甚至两者一起使用,以实现你的需求。

如果你需要灵活和有条件的定位,请使用 Flexbox。如果要创建需要相同大小的元素或具有表格形式的列表或类似结构,请使用 Grid。

作为前端开发人员,你需要了解这两者。

Flexbox 参考指南Grid 参考指南

P.S. 如果以上内容由遗漏,请在 Twitter 告诉我,我会再写一篇 :-)

原文:Flexbox vs Grid - How to Build the Most Common HTML Layouts,作者:Ondrej Polesny