css grid 布局适合哪些场景
通过“是否需同时控制行和列”判断该用 Grid 还是 Flexbox,并给出页面骨架(grid-template-areas)、自适应卡片墙(auto-fit + minmax)及表单仪表盘等严格对齐场景的写法要点。
学完这篇你能判断出一个布局到底该不该上 CSS Grid,并且能直接照抄几个典型场景的写法,不再靠「感觉哪个新就用哪个」。
第一步:先用一句话判断维数——决定该不该用 Grid
这一步要做的,是看清你的布局需要「同时控制行和列」还是「只排一条线」,做完这一步你就能排除掉一半不该用 Grid 的场合。判断标准很简单:如果每个元素的位置由「第几行 + 第几列」两个坐标共同确定,用 Grid;如果只是让一堆块沿着一个方向排开、自动换行,用 Flexbox 更省事。
/* 二维:行和列都要管 —— Grid */
.layout { display: grid; grid-template-columns: 240px 1fr; grid-template-rows: 64px 1fr 48px; }
/* 一维:只管横向排开 —— Flexbox */
.tags { display: flex; flex-wrap: wrap; gap: 8px; }
注意:
grid-template-columns只写一列(比如1fr)再用 Grid,基本等于白写,维护成本却比 Flexbox 高。
第二步:页面整体骨架是最典型的 Grid 场景
这一步给整页搭出「头部 / 侧栏 / 主内容 / 页脚」的框架,做完你会得到一个行高固定、列宽自适应、结构一眼可读的页面外壳。用 grid-template-areas 把名字写进布局里,改版时只需要动这几行文本,不用去翻每个子元素的宽高。
body {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
grid-template-rows: 64px 1fr 48px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
gap: 16px;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
注意:主内容列一定要写
minmax(0, 1fr)而不是1fr,否则里面的长表格、长代码块会把列撑破,出现横向滚动条。
第三步:等宽等高卡片墙,用 auto-fit + minmax 一行搞定
这一步处理「卡片列表在不同屏幕宽度下自动决定几列」,做完你不需要写任何媒体查询,卡片就能从 4 列一路平滑降到 1 列。关键是 repeat() 配 auto-fit,让浏览器自己去算能塞几列。
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 20px;
}
同一行的卡片默认等高,这正好是 Grid 相比浮动和老式 inline-block 最省心的地方。
注意:
auto-fill和auto-fit不一样。列数不够时auto-fill会留下空白列,卡片不会拉伸;想要卡片撑满整行用auto-fit。
第四步:需要严格对齐的表单、仪表盘、图片墙
这一步解决「标签列宽统一、控件左边缘对齐」这类强迫症需求,做完你会发现再也不需要给每个 label 写死 width: 120px。表单用两列 Grid,标签列固定、控件列自适应;仪表盘用 grid-template-columns: repeat(12, 1fr) 做 12 栅格,每个面板用 grid-column: span 4 占位。
.form { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 12px 16px; align-items: center; }
.dashboard { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px; }
.panel-wide { grid-column: span 8; }
.panel-narrow { grid-column: span 4; }
图片墙同理,grid-auto-rows: 200px 加个别子项 grid-row: span 2,就能做出大小错落的瀑布效果。
第五步:元素需要重叠时,Grid 比绝对定位干净
这一步让标题压在封面图上、让加载遮罩盖住卡片,做完你能少写一堆 position: relative 加 position: absolute。把多个子元素放进同一个 grid-area,它们自然叠在一起,再用 z-index 控制层级。
.cover { display: grid; }
.cover > * { grid-area: 1 / 1; } /* 所有子元素叠在同一格 */
.cover img { width: 100%; height: 100%; object-fit: cover; }
.cover h2 { align-self: end; padding: 16px; z-index: 1; }
注意:叠加后子元素默认按文档顺序叠放,后出现的在上层,别指望不写
z-index就一定是你想要的那张在上面。
第六步:确认哪些情况别用 Grid
这一步帮你避免「为了用而用」,做完你手上就有一套明确的分工。纯一维的导航条、按钮组、图标加文字,用 Flexbox 更短;让文字围绕图片流式排列,用 float 或多列布局;需要兼容非常老的内核时,Grid 支持度要单独确认(Chrome 57、Firefox 52、Safari 10.1 起支持,IE11 只支持带 -ms- 前缀的老语法,实际项目基本可以放弃)。
调试时打开 Chrome DevTools → Elements 面板右侧的 Layout 标签页 → 勾选 Grid,页面上会直接画出网格线和区域名,比反复改数值猜位置快得多。
小结
- 需要同时控制行和列的二维布局用 Grid,一维排列用 Flexbox。
- 页面整体骨架用
grid-template-areas,改版只动几行文本。 - 卡片墙用
repeat(auto-fit, minmax(260px, 1fr)),免媒体查询。 - 主内容列写
minmax(0, 1fr),防止长内容撑破布局。 - 表单、仪表盘、图片墙靠固定列 +
span对齐,别写死宽度。 - 元素重叠用同一个
grid-area叠放,比绝对定位干净。 - 调试靠 DevTools 的 Layout → Grid 勾选框看网格线。
转载请注明出处,版权归原作者所有。