Flexbox解决了一维布局的问题,但如果是二维网格布局呢?比如仪表盘、图片墙、复杂的后台页面------Flexbox就有点力不从心了。
CSS Grid就是为二维布局而生的。
Grid基础概念
css
.container {
display: grid;
/* 定义列:3列,每列200px */
grid-template-columns: 200px 200px 200px;
/* 定义行 */
grid-template-rows: 100px auto 100px;
/* 列间距和行间距 */
gap: 16px;
}
fr单位是Grid的特色------表示剩余空间的比例:
css
.container {
display: grid;
/* 左边200px固定,右边占满剩余空间 */
grid-template-columns: 200px 1fr;
/* 三列等分 */
grid-template-columns: 1fr 1fr 1fr;
/* 或简写 */
grid-template-columns: repeat(3, 1fr);
/* 自适应列数(每列最小200px,自动填充) */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
项目定位
css
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
gap: 10px;
}
/* 项目A:跨1行2列 */
.item-a {
grid-column: 1 / 3; /* 从第1条线到第3条线 */
grid-row: 1 / 2;
}
/* 项目B:跨2行1列 */
.item-b {
grid-column: 3 / 4;
grid-row: 1 / 3;
}
/* 简写 */
.item-c {
grid-area: 2 / 1 / 4 / 3; /* 行起/列起/行止/列止 */
}
命名区域:最直观的布局方式
css
.page {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: 60px 1fr 40px;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
看到代码就知道布局长什么样,非常直观。
对齐方式
css
.container {
display: grid;
/* 整个网格在容器中的对齐 */
justify-content: center; /* 水平居中 */
align-content: center; /* 垂直居中 */
/* 网格项目在每个单元格中的对齐 */
justify-items: stretch; /* 水平拉伸(默认) */
align-items: stretch; /* 垂直拉伸(默认) */
}
/* 单个项目的对齐(覆盖容器设置) */
.item {
justify-self: center;
align-self: center;
}
实战:响应式卡片列表
css
/* 自适应卡片网格 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
padding: 24px;
}
.card {
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.2s;
}
.card:hover {
transform: translateY(-4px);
}
auto-fill + minmax的组合非常强大------不需要写媒体查询,Grid会自动计算能放多少列。
Grid vs Flexbox
| 对比 | Grid | Flexbox |
|---|---|---|
| 维度 | 二维(行列同时控制) | 一维(行或列) |
| 布局方式 | 先定义网格,再放内容 | 内容决定布局 |
| 对齐 | 更强大 | 够用 |
| 适用场景 | 页面整体布局 | 组件内部布局 |
| 浏览器支持 | IE不支持,其他都行 | 几乎全部 |
实际项目中两者经常配合使用:Grid做页面大框架,Flexbox做组件内部排列。
隐式网格
当项目数量超过定义的网格时,Grid会自动创建隐式行/列:
css
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* 只定义了列,行是自动的 */
grid-auto-rows: minmax(100px, auto); /* 隐式行的最小高度 */
}
CSS Grid是二维布局的终极方案。学会了grid-template-columns和grid-template-areas,大部分复杂布局都能轻松搞定。
建议打开CodePen试试,Grid的可视化调试工具非常好用。