DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 的免费积分!
grid-template-areas
CSS 属性允许您定义和命名 CSS 网格容器中的单元格(或“区域”)。
.grid-container {
display: grid;
grid-template-areas: "header header" "sidebar main";
}
因此,上面的示例?我们得到一个 2x2 的网格,其中顶行保留两列,用于名为 header
的区域。底行也得到两列,但分别保留给名为 sidebar
和 main
的网格区域。

这意味着我们已经建立了网格,并且已经定义了网格区域,但实际上没有将任何内容分配给这些网格区域。如果我们想将元素放置在网格区域中,我们必须使用该元素上的 grid-area
属性明确声明它。
.grid-container {
display: grid;
grid-template-areas: "header header" "sidebar main";
}
.grid-header {
grid-area: header;
}
.grid-sidebar {
grid-area: sidebar;
}
.grid-content {
grid-area: main;
}
需要注意的是,网格区域必须是网格容器中的单个单元格,或者是一组相邻的单元格,且必须是 **矩形**。这意味着以下所有示例都是有效的。

但我们无法做到的是形成非矩形的网格区域。因此,如果您要定义的区域更像是“T”形或“L”形,那么就无能为力了。

语法
grid-template-areas: none | <string>
- 初始值:
none
- 应用于:网格容器
- 继承:否
- 计算值:如指定,关键字
none
或字符串值列表 - 动画类型:离散
值
/* Keyword value */
grid-template-areas: none;
/* <string> values */
grid-template-areas: "col-1 col-2 col-3";
grid-template-areas: "header header header" "sidebar main main";
grid-template-areas: "header header header"
"sidebar main main"
". footer footer";
/* Global values */
grid-template-areas: inherit;
grid-template-areas: initial;
grid-template-areas: revert;
grid-template-areas: unset;
none
这是 **默认** 值。正如您可能猜到的,none
表示没有在网格容器上设置命名的网格区域和显式网格轨道。这也意味着 网格轨道是隐式生成的,它们的大小由 grid-auto-columns
和 grid-auto-rows
属性定义。
除了使用 grid-template-areas
之外,实际上还有另一种创建显式网格轨道的方法,那就是使用 grid-template-columns
和 grid-template-rows
属性。我们将在本文后面更详细地介绍这一点。
<string>
字符串可以是您想要为特定网格模板区域指定的任何名称。因此,如果您的网格容器中有一行,并且您希望布局的标题放在那里,您可以将该区域命名为“header”或“page-top”,或者您想要的任何名称。实际上,如果该行中有多列,我们可以将每一列都命名为不同的网格区域。
.grid {
grid-template-areas: "logo menu utility-nav";
}
请注意,该示例中的整个三列行都被括在引号中。这一点至关重要,因为用引号括起来的命名网格模板区域表示新行。因此,如果我们有两行,我们将看到两组引号区域。
.grid {
grid-template-areas: "logo menu utility-nav" "sidebar-1 content sidebar-2";
}
更妙的是,我们可以通过将每一行写在自己的行上来使这一点更容易理解。
.grid {
grid-template-areas:
"logo menu utility-nav"
"sidebar-1 content sidebar-2";
}
字符串的语法可以实现跨越和跳过网格容器中的单元格等功能。我们稍后会讲到这一点。
基本用法
首先,让我们使用父网格容器上的 grid-template-areas
属性来定义网格模板区域。
.grid {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
}
目前,网格容器已命名区域,但其中没有任何内容。要将元素放置在其中,我们需要使用要放置的元素上的 grid-area
属性将命名的网格区域分配给该元素。
header {
grid-area: header;
}
aside {
grid-area: sidebar;
}
main {
grid-area: main;
}
footer {
grid-area: footer;
}
这是根据我们在父网格容器上定义的 grid-template-areas
获得的结果。

调整网格命名区域的大小
可以使用父网格容器上的 grid-template-columns
和 grid-template-rows
属性设置网格轨道的尺寸。
假设我们有一个布局要求,我们的网格需要两列,第二列占用的空间是第一列的两倍。我们可以使用 分数 (fr
) 单位 来实现这一点。
.grid {
display: grid;
gap: 1rem;
grid-template-columns: 1fr 2fr;
grid-template-areas: "sidebar main";
}
对于行来说也是一样的。假设我们现在需要在 3x3 的网格中实现以下布局。

这一次,我们将第一行和第三行设置为 250px
的固定高度,但调整中间行的尺寸,使其占用内容所需的空间。
.grid {
display: grid;
gap: 1rem;
grid-template-rows: 250px auto 250px;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
}
如果您想知道所有这些重复的命名网格模板区域是怎么回事,那是因为......
跨越单元格和行
重复命名区域可以连接单元格。因此,如果目标是创建一个名为 feature
的命名区域,并使其占用顶行中的两列,我们可以执行以下操作。
/* Valid declaration */
grid-template-areas: "feature feature widget";
很酷,如果同一命名区域在每一行都开始,我们也可以在垂直方向上执行类似的操作。
/* Valid declaration */
grid-template-areas:
"feature aside widget-1"
"feature aside widget-2";
当然,我们可以将两者结合起来,创建一个跨越两个方向的网格模板区域。
/* Valid declaration */
grid-template-areas:
"feature feature widget-1"
"feature feature widget-2";
如前所述,网格模板区域必须是矩形的。这意味着以下最后一个示例的变体无效。
/* Invalid declaration */
grid-template-areas:
"feature feature widget-1"
"feature aside widget-2";
我们可以在单元格之间创建间隙(或硬“停止”)
可以使用点 (.
) 符号来实现这一点。
grid-template-areas:
"header header header"
"sidebar main main"
". footer footer"; /* first cell is empty */
}
点的数量无关紧要。我们可以这样做。
grid-template-areas:
"header header header"
"sidebar main main"
"....... footer footer"; /* first cell is empty */
}
这两个声明都创建了相同的网格。

空白是可视化网格的好方法
以下声明是等效的,但第二个声明更容易可视化网格的结构,因为我们使用空空白来对齐名称。
grid-template-areas:
"header header header"
"sidebar main main"
". footer footer";
grid-template-areas:
"header header header"
"sidebar main main"
". footer footer";
如果您正在寻找另一种可视化网格容器的方法,Chris 有一个巧妙的想法,即在 CSS 注释中使用 ASCII 格式“绘制”网格,以便在 CSS 注释中使用 ASCII 格式“绘制”网格,以便快速参考。.
行必须具有相同数量的列
所有列表必须具有相同数量的值,否则声明无效。
/* 👍 */
grid-template-areas:
"name name-2 name-3"
"name name-2 name-3"
"name name-2 name-3";
/* 👍 */
grid-template-areas:
"header header"
". main"
"footer footer";
/* 👎 */
grid-template-areas:
"name name-2 name-3"
"name name-2 name-3"
"name name-3";
使用 Unicode 字符命名网格区域
根据规范,任何不符合 <ident>
语法的名称,在其他属性中按名称引用该区域时都需要转义。 例如,在下面的声明中,第一个区域的名称以数字开头,因此不符合 <ident>
语法。
.grid {
grid-template-areas: "1st b c";
}
解决方法是声明 1
数字的未转义 十六进制代码。在本例中,十六进制代码为 U+0031
,我们在 CSS 中将其转义为 \31st
。因此,我们使用它将元素分配到该命名网格区域。
.grid-item {
grid-area: \31st;
}
隐式分配的线名称
使用 grid-template-areas
属性定义轨道,我们可以根据分配的名称免费获得线名称。这与 grid-template-rows
和 grid-template-columns
属性不同,在定义列和行时,我们需要提供线名称。grid-template-areas
属性并非如此,因为它会获取我们提供的名称,并为我们输出轨道名称。
每个网格模板区域名称都会创建四条网格线。如果我们有一个名为 sidebar
的网格模板区域,我们将获得两对名为 sidebar-start
和 sidebar-end
的轨道线——一对用于列方向,一对用于行方向。

您可能想知道,如果我们显式定义轨道名称,并使用与隐式定义相同的名称——例如显式定义名为 sidebar-start
的网格线用于名为 sidebar
的区域会发生什么?两条线可以共存并被分配给不同的元素。换句话说,显式值仍然有效,并且两条线都可以使用。
隐式命名区域
在网格容器中命名网格区域的另一种方法是,在设置 grid-template-columns
和 grid-template-rows
属性上的轨道名称时,让 CSS 网格为我们隐式命名它们。
我们只需要为网格区域选择一个名称,并在其后面添加 -start
和 -end
作为轨道名称。例如,在这里,我们得到一个名为 sidebar
的网格模板区域,甚至没有声明 grid-template-areas
属性。
.grid-container {
display: grid;
grid-template-columns: [sidebar-start] 250px [sidebar-end] 1fr;
}
aside {
grid-area: sidebar;
}
如上例所示,虽然没有 grid-template-areas
属性显式定义名为“sidebar”的区域,但该区域仍然可以通过网格放置属性(如 grid-area
、grid-row
、grid-column
或其完整写法)进行引用。
示例:响应式圣杯布局
在以下演示中,我们使用 grid-template-areas
属性 使用 CSS 网格创建著名的圣杯布局
此布局之所以得名,是因为在 使用浮动进行布局 的时代,它难以置信地难以实现。谢天谢地,我们有了 CSS 网格,使它几乎微不足道。
首先,我们的 HTML
<div class="grid">
<header>Header</header>
<main>Main Content</main>
<aside class="left-sidebar">Left Sidebar</aside>
<aside class="right-sidebar">Right Sidebar</aside>
<footer>Footer</footer>
</div>
到目前为止很简单,对吧?我们希望标题位于顶部,页脚位于底部,并且主要内容位于中间行的三列之一。
我们可以在 CSS 中设置命名网格模板区域,并在需要时跨行。
.container {
grid-template-columns: 12rem auto 12rem;
grid-template-areas:
"header header header"
"left-sidebar main right-sidebar"
"footer footer footer";
}
现在我们需要将每个元素分配到一个命名网格区域。
header {
grid-area: header;
}
main {
grid-area: main;
}
footer {
grid-area: footer;
}
.left-sidebar {
grid-area: left-sidebar;
}
.right-sidebar {
grid-area: right-sidebar;
}
嗯,我们实际上完成了!这就是全部。我们可以通过默认情况下垂直堆叠网格区域,然后在更大的屏幕上构建圣杯布局来更进一步,在那里它看起来好多了。
.container {
display: grid;
grid-template-areas:
/* Each area is a row */
"header"
"nav"
"article"
"sidebar"
"footer";
}
@media (min-width: 600px) {
.container {
grid-template-columns: 12rem auto 12rem;
grid-template-areas:
/* Build the Holy Grail layout */
"header header header"
"nav article article"
"sidebar article article"
"footer footer footer";
}
}
浏览器支持
更多信息
- CSS 网格布局模块级别 2
- 简单的命名网格区域(Chris Coyier)
- 显式和隐式网格之间的区别(Manuel Matuzovic)
- 关于 CSS 网格布局的学习(Oliver Williams)