CSS Grid 网格布局
CSS Grid 是二维布局的终极方案——它能同时对行和列进行精确控制。如果说 Flexbox 是”一维流水线”,Grid 就是”二维棋盘”。
启用 Grid
css
.container {
display: grid;
} 容器成为网格容器,直接子元素成为网格项。
定义网格结构
grid-template-columns / grid-template-rows
定义网格有多少列、多少行,以及它们的尺寸:
css
.grid {
display: grid;
grid-template-columns: 200px 1fr 200px;
/* 三列:左 200px、中间弹性、右 200px */
grid-template-rows: auto 1fr auto;
/* 三行:上下按内容、中间弹性 */
} fr 单位
fr(fraction,份数)是 Grid 特有的单位,表示剩余空间的比例:
css
/* 等分三列 */
.grid {
grid-template-columns: 1fr 1fr 1fr;
}
/* 中间列是两侧的两倍宽 */
.grid {
grid-template-columns: 1fr 2fr 1fr;
} repeat() 函数
简化重复的列定义:
css
/* 12 列等宽网格 */
.grid-12 {
grid-template-columns: repeat(12, 1fr);
}
/* 两列模式交替 */
.grid-pattern {
grid-template-columns: repeat(3, 1fr 2fr);
/* 1fr 2fr 1fr 2fr 1fr 2fr */
} 间距:gap
与 Flexbox 一样,gap 控制网格项之间的间距:
css
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem; /* 行列间距相同 */
gap: 1rem 2rem; /* 行间距 列间距 */
} 网格项放置
默认情况下,网格项按顺序从左到右、从上到下自动放置。你也可以手动指定位置:
css
/* 让 header 跨越整行 */
.header {
grid-column: 1 / -1; /* 从第一根线到最后根线 */
}
/* 让 sidebar 放在第一列 */
.sidebar {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
/* 精确定位 */
.item {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
} 1 / -1 是常用写法:-1 代表最后一条网格线,1 / -1 就是”从第一条到最后一条”即占满整行/整列。
grid-area 简写
css
.item {
grid-area: row-start / col-start / row-end / col-end;
/* 等价: */
grid-area: 1 / 2 / 3 / 4;
} 命名的区域模板
grid-template-areas 让你用可视化方式描述布局:
css
.layout {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
gap: 1rem;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; } html
<div class="layout">
<header class="header">页头</header>
<nav class="sidebar">侧栏</nav>
<main class="content">内容</main>
<aside class="aside">附加</aside>
<footer class="footer">页脚</footer>
</div> grid-template-areas 是最直观的布局方式——你可以在 CSS 中用文字”画”出页面布局。适合固定结构的页面(如后台管理面板、文档站)。
响应式自动网格
auto-fit 与 auto-fill
无需媒体查询即可创建响应式网格:
css
/* 自适应卡片网格:每列最小 250px,空间充裕时自动增加列数 */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
} auto-fit:拉伸现有项以填满空间auto-fill:留出空白列,不拉伸现有项
这是 Grid 最强大的特性之一——repeat(auto-fit, minmax(250px, 1fr)) 可以在不使用任何媒体查询的情况下实现完美的响应式网格。它相当于告诉浏览器:“每列至少 250px,空间够就多放几列,不够就自动换行”。
对齐方式
| 属性 | 作用 | 写在 |
|---|---|---|
justify-items | 单元格内的水平对齐 | 容器 |
align-items | 单元格内的垂直对齐 | 容器 |
justify-content | 网格整体水平对齐 | 容器 |
align-content | 网格整体垂直对齐 | 容器 |
justify-self | 单个项的水平对齐 | 子项 |
align-self | 单个项的垂直对齐 | 子项 |
css
.grid {
display: grid;
justify-items: center; /* 所有项在单元格内水平居中 */
align-items: center; /* 所有项在单元格内垂直居中 */
/* 简写 */
place-items: center;
}
.special {
justify-self: start; /* 单独这个项左对齐 */
align-self: end; /* 单独这个项底对齐 */
} 隐式网格
当你定义的格子不够用时,Grid 会自动创建隐式行(implicit rows):
css
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 150px; /* 隐式行的高度 */
} Grid vs Flexbox
| 特性 | Flexbox | Grid |
|---|---|---|
| 布局维度 | 一维(行 or 列) | 二维(行 and 列) |
| 内容优先/布局优先 | 内容驱动 | 布局驱动 |
| 适合场景 | 导航栏、工具栏、行内元素排列 | 页面骨架、卡片网格、表单布局 |
| 典型语法 | flex-direction, justify-content | grid-template-columns, grid-template-areas |
Grid 和 Flexbox 不是互斥的——它们可以协同工作。一个常见模式是:页面整体用 Grid 划分区域,每个区域内部用 Flexbox 排列子元素。选择哪个取决于”这个容器内需要几维的控制”。