CSS 零基础教程

CSS grid-template-areas 属性

grid-template-areas 提供了一种强大的方法,可以直接在 CSS 中可视化地定义网格布局的结构。

你不再需要仅仅依赖网格线编号或名称来放置项目,而是可以使用命名区域来创建一个更直观的布局表示。这种方法增强了代码的可读性,并简化了修改过程,对于复杂的布局尤其有用。它让你能一眼看清网格的整体结构,使其更易于理解和维护。

1. 理解 grid-template-areas

网格容器的 grid-template-areas 属性允许你在网格布局中定义命名网格区域 (Named Grid Areas)。每个命名网格区域对应一个或多个网格单元格。然后,你使用 grid-area 属性将网格项目分配给这些区域。

与使用行号或命名网格线相比,这种方法提供了一种更直观、更像“画图”的方式来定义网格布局。

语法涉及将网格表示为一系列的行,其中每一行都是一个包含网格区域名称的字符串。共享相同名称的区域被视为跨越这些网格单元格。

以下是关键原则的细分:

  1. 命名区域: 为布局的不同部分选择描述性名称(例如:headernavmainsidebarfooter)。
  2. 定义网格: 使用 grid-template-areas 属性将这些名称映射到网格上。值中的每一行代表网格中的一行。在每一行内,你指定每列的区域名称,用空格分隔。
  3. 分配项目: 在网格项目上使用 grid-area 属性,将它们分配给你定义的命名区域。

2. 基础示例

让我们考虑一个简单的布局,包含页头、主要内容区域、侧边栏和页脚。

CSS:

.container {
  display: grid;
  grid-template-columns: 1fr 200px; /* 主要内容占据剩余空间,侧边栏 200px */
  grid-template-rows: auto 1fr auto; /* 页头和页脚自动大小,主要内容占据剩余垂直空间 */
  grid-template-areas:
    "header header"
    "main   sidebar"
    "footer footer";
  height: 100vh; /* 确保网格占据整个视口高度 */
}
.header {
  grid-area: header;
  background-color: #eee;
  padding: 10px;
}
.main {
  grid-area: main;
  background-color: #ddd;
  padding: 10px;
}
.sidebar {
  grid-area: sidebar;
  background-color: #ccc;
  padding: 10px;
}
.footer {
  grid-area: footer;
  background-color: #bbb;
  padding: 10px;
}

HTML:

<div class="container">
  <header class="header">页头 (Header)</header>
  <main class="main">主要内容 (Main Content)</main>
  <aside class="sidebar">侧边栏 (Sidebar)</aside>
  <footer class="footer">页脚 (Footer)</footer>
</div>

在这个例子中:

  • grid-template-columns: 1fr 200px; 创建了两列。第一列 (1fr) 占据剩余的可用空间,第二列宽 200px。
  • grid-template-rows: auto 1fr auto; 创建了三行。页头和页脚行将根据其内容调整大小 (auto),中间行 (1fr) 将占据剩余的垂直空间。
  • grid-template-areas 使用命名区域定义了整体结构。
  • 每个网格项目 (header, main, sidebar, footer) 都使用 grid-area 属性分配到了其对应的区域。

3. 跨越行和列

通过重复区域名称,你可以轻松地让网格区域跨越多行或多列。

CSS:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   sidebar"
    "footer footer footer";
  height: 100vh;
}
.header {
  grid-area: header;
  background-color: #eee;
  padding: 10px;
}
.nav {
  grid-area: nav;
  background-color: #ddd;
  padding: 10px;
}
.main {
  grid-area: main;
  background-color: #ccc;
  padding: 10px;
}
.sidebar {
  grid-area: sidebar;
  background-color: #bbb;
  padding: 10px;
}
.footer {
  grid-area: footer;
  background-color: #aaa;
  padding: 10px;
}

HTML:

<div class="container">
  <header class="header">页头</header>
  <nav class="nav">导航</nav>
  <main class="main">主要内容</main>
  <aside class="sidebar">侧边栏</aside>
  <footer class="footer">页脚</footer>
</div>

在这里,headerfooter 跨越了所有三列,因为在 grid-template-areas 定义中,它们的名称在整行中重复出现了三次。

4. 使用点号语法表示空单元格

你可以使用点号 (.) 来表示一个空的网格单元。这对于在布局中创建视觉间隙或留白非常有用。点号可以连在一起写,表示多个空单元格。

CSS:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-areas:
    "header  header"
    "main    .     "
    "footer  footer";
  height: 100vh;
}
.header {
  grid-area: header;
  background-color: #eee;
  padding: 10px;
}
.main {
  grid-area: main;
  background-color: #ddd;
  padding: 10px;
}
.footer {
  grid-area: footer;
  background-color: #bbb;
  padding: 10px;
}

HTML:

<div class="container">
  <header class="header">页头</header>
  <main class="main">主要内容</main>
  <footer class="footer">页脚</footer>
</div>

在这种情况下,.main 区域的右侧创建了一个空单元格。注意,你可以使用多个点号字符(例如 ...)来表示多个空单元格,这有助于在处理更复杂的布局时提高代码的可读性(对齐代码中的列)。

5. 规则和限制

  • 矩形区域: 命名网格区域必须是矩形的。你不能创建 L 形或其他不规则形状的区域。
  • 完整的行/列: grid-template-areas 定义中的每一行必须具有相同数量的列,并且每一列必须具有相同数量的行。
  • 有效名称: 区域名称必须是有效的 CSS 标识符。
  • 不可重命名: 你不能在 grid-template-areas 属性内重命名网格区域。每个区域名称在整个网格定义中必须保持一致。

6. 实战案例与演示

让我们探索更复杂的例子,展示 grid-template-areas 的多功能性。

6.1 带有嵌套网格的复杂布局

你可以将 grid-template-areas 与嵌套网格结合使用,以创建精致的布局。考虑一个包含页头、导航、带有子部分的主要内容区域、侧边栏和页脚的布局。

CSS:

.container {
  display: grid;
  grid-template-columns: 200px 1fr 300px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header  header"
    "nav    main    sidebar"
    "footer footer  footer";
  height: 100vh;
}
.header {
  grid-area: header;
  background-color: #eee;
  padding: 10px;
}
.nav {
  grid-area: nav;
  background-color: #ddd;
  padding: 10px;
}
.main {
  grid-area: main;
  background-color: #ccc;
  padding: 10px;
  /* 主要内容的嵌套网格 */
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "article"
    "aside";
}
.main > article {
  grid-area: article;
  background-color: #bbb;
  padding: 10px;
}
.main > aside {
  grid-area: aside;
  background-color: #aaa;
  padding: 10px;
}
.sidebar {
  grid-area: sidebar;
  background-color: #999;
  padding: 10px;
}
.footer {
  grid-area: footer;
  background-color: #888;
  padding: 10px;
}

HTML:

<div class="container">
  <header class="header">页头</header>
  <nav class="nav">导航</nav>
  <main class="main">
    <article>文章</article>
    <aside>相关内容</aside>
  </main>
  <aside class="sidebar">侧边栏</aside>
  <footer class="footer">页脚</footer>
</div>

在这个例子中,main 元素本身就是一个网格容器,它使用 grid-template-areas 将其内部内容构建为 articleaside。这演示了如何嵌套网格以创建更复杂和模块化的布局。

6.2 处理重叠内容(避免)

虽然 grid-template-areas 擅长定义清晰且不重叠的布局,但你应该避免创建网格区域重叠的情况。重叠会导致不可预测的渲染,并使你的布局难以理解和维护。如果你需要元素在视觉上重叠,请考虑在网格项目中使用绝对定位或其他技术。

6.3 可视化网格

在使用 grid-template-areas 时,一个有用的技巧是在 CSS 中临时添加视觉辅助,以便更清楚地看到网格结构。你可以通过为每个网格区域添加背景颜色来实现这一点:

CSS:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   sidebar"
    "footer footer footer";
  height: 100vh;
}
.header {
  grid-area: header;
  background-color: rgba(238, 238, 238, 0.5); /* 半透明背景 */
  padding: 10px;
}
.nav {
  grid-area: nav;
  background-color: rgba(221, 221, 221, 0.5); /* 半透明背景 */
  padding: 10px;
}
.main {
  grid-area: main;
  background-color: rgba(204, 204, 204, 0.5); /* 半透明背景 */
  padding: 10px;
}
.sidebar {
  grid-area: sidebar;
  background-color: rgba(187, 187, 187, 0.5); /* 半透明背景 */
  padding: 10px;
}
.footer {
  grid-area: footer;
  background-color: rgba(170, 170, 170, 0.5); /* 半透明背景 */
  padding: 10px;
}

通过为每个网格区域添加半透明背景色,你可以轻松地可视化网格的结构,并识别任何意外的间隙或重叠。一旦你对布局满意,记得移除这些视觉辅助。