CSS 网格布局
Web 的新布局模块
在 Web 出现之前,人们早已在杂志、报纸、海报等中长期使用网格设计。当 Web 开发人员开始创建网页时,许多网页都基于网格布局。不同的解决方案已被用于创建网格布局,例如表格、浮动、内联块或弹性盒,但当你尝试定义复杂的网格设计时,所有这些技术都存在不同的问题。
为了解决这些问题,定义了一个新标准,为创建网格设计提供了良好的解决方案。这个规范被称为 CSS 网格布局,它允许用户在 Web 上非常轻松地创建二维布局。它专为此目的而设计,带来了非常强大的功能,可以将网页划分为不同的区域,为网页作者提供了极大的灵活性,以定义不同部分的大小以及元素在每个部分中的位置。
网格布局已在 WebKit 中开发了一段时间,您今天就可以在 Safari 技术预览版中使用 WebKit 体验网格布局。
基本概念
网格是由一系列相交线构成的结构。CSS 网格布局规范的主要概念是
- 定义网格的 网格线:它们可以是水平的或垂直的,
并且从 1 开始编号。 - 网格轨道,它们是网格中定义的行(水平)
或列(垂直)。 - 网格单元格,行与列的交点。
- 网格区域,一个或多个相邻的网格单元格,定义一个矩形。
网格定义
要创建网格,您只需为 display
属性使用一个新值:grid
或 inline-grid
。这与 Flexbox 的语法相同,因此您可能已经习惯了。
然后您需要定义网格的结构。例如,要定义轨道的大小,您可以这样做
display: grid;
grid-template-rows: 100px 100px;
grid-template-columns: 400px 200px 100px;
这将创建一个两行网格,每行高 100px,以及三列,第一列宽 400px,第二列宽 200px,第三列宽 100px。此网格将有四条垂直线(1、2、3、4)和三条水平线(1、2、3)。您还可以为线条命名,以便稍后轻松引用它们。例如
grid-template-columns: [first] 400px [main] 200px [side] 100px [last];
关于轨道大小,您有很多灵活性
- 您可以定义固定大小的轨道,设置长度或百分比。
- 您可以定义固有大小的轨道,其大小基于其内容的大小,使用
auto
、min-content
、max-content
或fit-content
。 - 您可以使用新单位
fr
来利用可用空间。
此外,还有一些函数可用于设置轨道大小
minmax()
,用于设置轨道的最小和最大尺寸,因此其尺寸最终将取决于可用空间和其余轨道的大小。repeat()
,用于定义固定数量的重复。它也可以在自动模式下使用,使轨道的数量取决于可用空间。
有一种特殊的语法允许您使用 ASCII 艺术定义网格结构
grid-template-areas: "header header"
"sidebar main "
"sidebar footer";
在此示例中,我们创建了一个 2×3 的网格,其中第一行是页眉,第一列的其余部分是侧边栏,主要内容位于第二行和第二列,页脚位于最后一行和最后一列。
您还可以定义轨道之间的间距。为此,您只需使用 grid-row-gap
和 grid-column-gap
属性。
项目放置
网格容器的子元素被称为 网格项。它们可以使用放置属性 grid-row-start
、grid-row-end
、grid-column-start
和 grid-column-end
在网格的不同部分进行定位。但在大多数情况下,您将使用简写形式 grid-row
、grid-column
和 grid-area
。
请注意,这些属性指的是网格线,因此如果您想将元素放在第三行和第二列,您可以使用类似以下的方式
grid-row: 3;
grid-column: 2;
项目也可以跨越多行,因此您可以使用以下语法来占据三行两列
grid-row: 2 / 5;
grid-column: 3 / span 2;

除此之外,您还可以使用这些属性引用命名行或区域,这在某些情况下非常方便。
可以想象,当您使用网格布局时,可以非常容易地打破 DOM 顺序和视觉顺序之间的关系。您必须注意保持 DOM 中的正确顺序,以避免降低内容的可访问性。
最后,还有一种可能性是让项目自行放置到网格中。如果您不设置任何放置属性(或使用 auto
),项目将自动放置到网格的某个空单元格中,并在需要时创建新行(默认情况下)或列(如果通过 grid-auto-flow
属性指定)。
对齐
使用 CSS 网格布局时,一个免费且重要的好处是支持对齐。在网格布局中,您只需一些简单的 CSS 属性即可轻松实现水平和垂直对齐。
网格布局的对齐功能作用于两个不同的主体:相对于网格容器的网格轨道,以及位于各自网格区域中的网格项。此外,我们可以在水平和垂直两个轴上进行操作。
CSS 属性 justify-content
和 align-content
分别用于水平和垂直对齐网格轨道。这些属性定义了所谓的 内容分布 行为,也可以用于按照不同的分布方式(例如:between、around、evenly 和 stretch)在轨道之间分配网格容器的可用空间。例如,查看以下网格
display: grid;
grid-template-rows: 100px 100px;
grid-template-columns: 150px 150px 150px;
height: 500px;
width: 650px;
align-content: center;
justify-content: space-evenly;

在对齐网格项时,justify-self
和 align-self
属性分别用于水平和垂直对齐。这些属性定义了网格项的 自身对齐 行为。通过使用 默认对齐 属性 align-items
和 justify-items
,可以为网格容器的所有项定义默认行为,这为定义网格的对齐行为提供了令人难以置信的语法灵活性。

使用网格实现响应式设计
正如您所能想象的,所有不同的网格布局属性都使得创建响应式设计更加舒适。您可以利用强大的轨道尺寸机制,例如 fr
单位、minmax()
或 repeat()
。将其与媒体查询结合使用,只需几行 CSS 代码即可完全改变网格的结构。
例如
display: grid;
grid-gap: 10px 20px;
grid-template-rows: 100px 1fr auto;
grid-template-columns: 1fr 200px;
grid-template-areas: "header header"
"content aside "
"footer aside ";
@media (max-width: 600px) {
grid-gap: 0;
grid-template-rows: auto 1fr auto auto;
grid-template-columns: 1fr;
grid-template-areas: "header "
"content"
"aside "
"footer ";
}

以及更多
这仅仅是一篇关于网格布局的入门博客文章,而不是对其提供所有不同功能的深入评论:那需要远不止一篇文章。本博客文章中解释的不同示例已在线发布。您现在就可以开始尝试它们了!
如果您想了解更多关于 CSS 网格布局的信息,这里有许多不错的资源
- Grid by Example 是 Rachel Andrew 的一个优秀网站,包含大量资源。
- Chris House 的CSS-Tricks 页面是一个非常好的参考资料。
- Jen Simmons 在她的网站上有一些很棒的示例。
最重要的是,许多人在不同的会议和活动中讨论了网格布局。您会很容易找到一些在线发布的演讲。
结论
CSS 网格布局将持续存在。我们期待很快在 Safari 和其他 Web 浏览器的发布版本中看到它。这对多年来一直等待此类工具的 Web 作者来说是个非常好的消息。我们相信这将是 Web 的一个巨大进步。
WebKit 中网格布局的实现由 Igalia 的 Web 平台团队完成,并由 Bloomberg 赞助。如果您有任何评论或问题,请随时联系参与此工作的人员:Javi (@lajava77)、Manuel (@regocas) 或 Sergio (@svillarsenin)。如果您想跟踪开发进度,可以关注bug #60731。非常欢迎新的错误报告,尤其是现在网格布局正在进入您的浏览器,测试比以往任何时候都更容易。激动人心的时刻即将来临!