CSS 网格布局
Web 的新布局模块

在 Web 出现之前,人们早已在杂志、报纸、海报等中长期使用网格设计。当 Web 开发人员开始创建网页时,许多网页都基于网格布局。不同的解决方案已被用于创建网格布局,例如表格、浮动、内联块或弹性盒,但当你尝试定义复杂的网格设计时,所有这些技术都存在不同的问题。

为了解决这些问题,定义了一个新标准,为创建网格设计提供了良好的解决方案。这个规范被称为 CSS 网格布局,它允许用户在 Web 上非常轻松地创建二维布局。它专为此目的而设计,带来了非常强大的功能,可以将网页划分为不同的区域,为网页作者提供了极大的灵活性,以定义不同部分的大小以及元素在每个部分中的位置。

网格布局已在 WebKit 中开发了一段时间,您今天就可以在 Safari 技术预览版中使用 WebKit 体验网格布局。

基本概念

网格是由一系列相交线构成的结构。CSS 网格布局规范的主要概念是

  • 定义网格的 网格线:它们可以是水平的或垂直的,
    并且从 1 开始编号。
  • 网格轨道,它们是网格中定义的行(水平)
    或列(垂直)。
  • 网格单元格,行与列的交点。
  • 网格区域,一个或多个相邻的网格单元格,定义一个矩形。
Grid Concepts

网格定义

要创建网格,您只需为 display 属性使用一个新值:gridinline-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];
Grid Definition

关于轨道大小,您有很多灵活性

  • 您可以定义固定大小的轨道,设置长度或百分比。
  • 您可以定义固有大小的轨道,其大小基于其内容的大小,使用 automin-contentmax-contentfit-content
  • 您可以使用新单位 fr 来利用可用空间。

此外,还有一些函数可用于设置轨道大小

  • minmax(),用于设置轨道的最小和最大尺寸,因此其尺寸最终将取决于可用空间和其余轨道的大小。
  • repeat(),用于定义固定数量的重复。它也可以在自动模式下使用,使轨道的数量取决于可用空间。

有一种特殊的语法允许您使用 ASCII 艺术定义网格结构

    grid-template-areas: "header  header"
                         "sidebar main  "
                         "sidebar footer";

在此示例中,我们创建了一个 2×3 的网格,其中第一行是页眉,第一列的其余部分是侧边栏,主要内容位于第二行和第二列,页脚位于最后一行和最后一列。

Grid Areas

您还可以定义轨道之间的间距。为此,您只需使用 grid-row-gapgrid-column-gap 属性。

项目放置

网格容器的子元素被称为 网格项。它们可以使用放置属性 grid-row-startgrid-row-endgrid-column-startgrid-column-end 在网格的不同部分进行定位。但在大多数情况下,您将使用简写形式 grid-rowgrid-columngrid-area

请注意,这些属性指的是网格线,因此如果您想将元素放在第三行和第二列,您可以使用类似以下的方式

    grid-row: 3;
    grid-column: 2;

项目也可以跨越多行,因此您可以使用以下语法来占据三行两列

    grid-row: 2 / 5;
    grid-column: 3 / span 2;
Grid Placement

除此之外,您还可以使用这些属性引用命名行或区域,这在某些情况下非常方便。

可以想象,当您使用网格布局时,可以非常容易地打破 DOM 顺序和视觉顺序之间的关系。您必须注意保持 DOM 中的正确顺序,以避免降低内容的可访问性。

最后,还有一种可能性是让项目自行放置到网格中。如果您不设置任何放置属性(或使用 auto),项目将自动放置到网格的某个空单元格中,并在需要时创建新行(默认情况下)或列(如果通过 grid-auto-flow 属性指定)。

对齐

使用 CSS 网格布局时,一个免费且重要的好处是支持对齐。在网格布局中,您只需一些简单的 CSS 属性即可轻松实现水平和垂直对齐。

网格布局的对齐功能作用于两个不同的主体:相对于网格容器的网格轨道,以及位于各自网格区域中的网格项。此外,我们可以在水平和垂直两个轴上进行操作。

CSS 属性 justify-contentalign-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;
Grid Alignment Tracks

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

Grid Alignment 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 ";
}
Responsive grid using flexible sizes and media queries

以及更多

这仅仅是一篇关于网格布局的入门博客文章,而不是对其提供所有不同功能的深入评论:那需要远不止一篇文章。本博客文章中解释的不同示例已在线发布。您现在就可以开始尝试它们了!

如果您想了解更多关于 CSS 网格布局的信息,这里有许多不错的资源

最重要的是,许多人在不同的会议和活动中讨论了网格布局。您会很容易找到一些在线发布的演讲。

结论

CSS 网格布局将持续存在。我们期待很快在 Safari 和其他 Web 浏览器的发布版本中看到它。这对多年来一直等待此类工具的 Web 作者来说是个非常好的消息。我们相信这将是 Web 的一个巨大进步。

WebKit 中网格布局的实现由 Igalia 的 Web 平台团队完成,并由 Bloomberg 赞助。如果您有任何评论或问题,请随时联系参与此工作的人员:Javi (@lajava77)、Manuel (@regocas) 或 Sergio (@svillarsenin)。如果您想跟踪开发进度,可以关注bug #60731。非常欢迎新的错误报告,尤其是现在网格布局正在进入您的浏览器,测试比以往任何时候都更容易。激动人心的时刻即将来临!