display: grid 是现代 HTML 页面级布局的事实标准,适用于后台页、仪表盘等多区域固定结构;它为唯一原生二维布局系统,可同时控制行列,而 Flexbox 仅支持一维对齐,嵌套实现模板易致层级深、响应式难、定位不灵活。

display: grid 是当前 HTML 模板主流的页面级布局模式,尤其适用于固定结构、多区域划分的模板场景(如后台管理页、仪表盘、内容型首页)。它不是“可选方案”,而是现代模板工程的事实标准——只要不强求 IE11 兼容,grid 就该是第一选择。
为什么不用 Flexbox 做整页模板布局?
Flexbox 是一维模型,适合处理「一行或一列内子元素的对齐与分配」,但页面模板天然需要二维控制:既要定义行(header / main / footer),又要定义列(sidebar / content / aside)。强行用 Flex 嵌套实现三栏+上下分区,会导致:
- 层级过深(比如
.container → .row → .col → .inner) - 响应式断点需在多层上重复写
flex-direction: column - 无法直接跨行/跨列定位某个模块(例如让 banner 占满 header + 部分 main)
- 父容器必须显式设高度(否则
flex: 1在无约束下不生效)
grid-template-areas 看起来直观,但实际项目里要慎用
命名区域写法像这样:
.template {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 240px 1fr 320px;
grid-template-rows: auto 1fr auto;
}
问题在于:
- 每个区域名(如
"sidebar")必须在所有子元素的grid-area中严格匹配,拼错就失效,且无运行时报错 - 加一个新模块(比如右上角通知角标)就得重写整个
grid-template-areas字符串 - 无法用
@media单独调整某块位置(比如移动端把aside移到main下方),只能整段替换字符串
更稳妥的做法是用线性定义 + 显式定位:
立即学习“前端免费学习笔记(深入)”;
.template {
display: grid;
grid-template-columns: 240px 1fr 320px;
grid-template-rows: auto 1fr auto;
gap: 16px;
}
.header { grid-row: 1; grid-column: 1 / -1; }
.sidebar { grid-row: 2; grid-column: 1; }
.main { grid-row: 2; grid-column: 2; }
.aside { grid-row: 2; grid-column: 3; }
.footer { grid-row: 3; grid-column: 1 / -1; }
模板中 Grid 的最小安全配置有哪些?
避免常见渲染异常,这几个 CSS 规则建议写进所有模板根容器:
- 必须设
min-height: 100vh,否则内容少时 footer 会塌陷到页面中部 - 用
gap(而非margin)控制模块间距,防止父子 margin 合并导致空白错位 - 子元素若含长文本或 URL,加
min-width: 0,否则grid-column: 2可能被撑爆宽度 - 避免对 Grid 容器设
text-align: center——Grid 子项默认不继承,居中得用justify-self: center或place-self: center
兼容性兜底不是靠 JS,而是 CSS 层级降级
如果项目仍需支持 IE11,不要试图用 JS 动态切换布局,而是在同一份 CSS 中用 @supports 提供降级:
.template {
display: flex;
flex-direction: column;
min-height: 100vh;
}
@supports (display: grid) {
.template {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
grid-template-rows: auto 1fr auto;
}
.header { grid-area: header; }
.main { grid-area: main; }
.footer { grid-area: footer; }
}
真正容易被忽略的是:Grid 布局下,overflow: hidden 必须写在具体子容器上,而不是 Grid 父容器——后者不会截断子项溢出,因为 Grid 容器本身不参与内容流裁剪。



















