Skip to content

CSS Grid 布局

CSS Grid Layout(网格布局)是 CSS 中一个强大的二维布局系统,它能够控制行和列,使我们能够创建复杂的网页布局。

什么是 Grid 布局?

Grid 布局是 CSS 中最强大的布局系统之一。与 Flexbox 的一维布局不同,Grid 是一个二维布局系统,可以同时控制行和列。这使得它非常适合创建复杂的网页布局。

基本概念

在深入了解 Grid 属性之前,让我们先了解一些基本概念:

  • Grid Container(网格容器):应用 display: grid 的元素
  • Grid Item(网格项):网格容器的直接子元素
  • Grid Line(网格线):构成网格结构的水平和垂直线条
  • Grid Track(网格轨道):两条相邻网格线之间的空间(行或列)
  • Grid Cell(网格单元):四个网格线包围的最小单位
  • Grid Area(网格区域):由四个网格线定义的矩形区域,可以包含任意数量的网格单元

创建网格容器

要创建一个网格容器,需要将元素的 display 属性设置为 grid 或 inline-grid:

css
.container {
  display: grid;
  /* 或者 */
  display: inline-grid;
}

定义网格轨道

使用 [grid-template-columns](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 和 [grid-template-rows](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 属性来定义网格的列和行:

css
.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 100px 100px;
}

这将创建一个 3 列 2 行的网格,每列宽度为 200px,每行高度为 100px。

使用 fr 单位

fr 单位代表网格容器中可用空间的一部分:

css
.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  grid-template-rows: 100px 100px;
}

在这个例子中,第一列和第三列各占 1 份,第二列占 2 份。

使用 repeat() 函数

为了简化重复的轨道,可以使用 repeat() 函数:

css
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* 等同于 grid-template-columns: 1fr 1fr 1fr; */
}

网格间距

使用 [grid-gap](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js)、[grid-row-gap](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 和 [grid-column-gap](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 属性来设置网格间距:

css
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
  /* 或者分别设置行间距和列间距 */
  grid-row-gap: 10px;
  grid-column-gap: 20px;
}

放置网格项

使用网格线

通过 [grid-column](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 和 [grid-row](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 属性来指定网格项的位置:

css
.item {
  grid-column: 1 / 3; /* 从第1条线开始,到第3条线结束 */
  grid-row: 1;        /* 放置在第1行 */
}

使用网格区域

通过 [grid-template-areas](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 属性创建命名区域:

css
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 100px 100px;
  grid-template-areas: 
    "header header header"
    "sidebar main main"
    "footer footer footer";
}

.header {
  grid-area: header;
}

.sidebar {
  grid-area: sidebar;
}

.main {
  grid-area: main;
}

.footer {
  grid-area: footer;
}

对齐网格项

对齐网格容器内的内容

使用 [justify-items](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 和 [align-items](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 属性来对齐网格容器内的所有网格项:

css
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 100px;
  justify-items: center; /* 水平对齐 */
  align-items: center;   /* 垂直对齐 */
}

对齐单个网格项

使用 [justify-self](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 和 [align-self](file:///Users/jry/Documents/WWW/xyito/lingyun/webstudy/node_modules/.vitepress/cache/deps/vue.js) 属性来对齐单个网格项:

css
.item {
  justify-self: start; /* 水平对齐 */
  align-self: end;     /* 垂直对齐 */
}

实际示例

响应式卡片布局

html
<div class="card-container">
  <div class="card">卡片 1</div>
  <div class="card">卡片 2</div>
  <div class="card">卡片 3</div>
  <div class="card">卡片 4</div>
  <div class="card">卡片 5</div>
  <div class="card">卡片 6</div>
</div>
css
.card-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  grid-gap: 20px;
  padding: 20px;
}

.card {
  background: #f0f0f0;
  padding: 20px;
  border-radius: 5px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

经典网页布局

html
<div class="page">
  <header class="header">头部</header>
  <nav class="nav">导航</nav>
  <main class="main">主要内容</main>
  <aside class="sidebar">侧边栏</aside>
  <footer class="footer">底部</footer>
</div>
css
.page {
  display: grid;
  grid-template-areas: 
    "header header header"
    "nav main sidebar"
    "footer footer footer";
  grid-template-rows: 80px 1fr 80px;
  grid-template-columns: 150px 1fr 150px;
  height: 100vh;
  gap: 10px;
}

.header {
  grid-area: header;
  background: #333;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

.nav {
  grid-area: nav;
  background: #ddd;
  padding: 20px;
}

.main {
  grid-area: main;
  background: #fff;
  padding: 20px;
  overflow-y: auto;
}

.sidebar {
  grid-area: sidebar;
  background: #eee;
  padding: 20px;
}

.footer {
  grid-area: footer;
  background: #333;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

浏览器兼容性

Grid 布局在现代浏览器中有很好的支持:

  • Chrome 57+
  • Firefox 52+
  • Safari 10.1+
  • Edge 16+
  • IE 10+ (部分支持,前缀 -ms-)

总结

CSS Grid 布局提供了一种强大而灵活的方式来创建复杂的网页布局。通过掌握网格容器、网格项、网格线、网格轨道和网格区域等概念,结合各种属性的使用,我们可以轻松实现各种复杂的布局需求。Grid 布局与 Flexbox 布局相辅相成,是现代 Web 开发中不可或缺的布局工具。