现代 CSS 布局的四个层次:从 Flexbox 到 Container Queries
一张清晰的地图:Flexbox 解决一维、Grid 解决二维、Subgrid 穿透嵌套、Container Queries 响应容器。用真实组件示例讲透它们各自的适用边界。
摘要:布局方案的选型不是「越新越好」,而是「用对层次」。本文用一个博客卡片组件贯穿全文,展示四种现代 CSS 布局技术各自的定位与取舍。
一张总览表
| 技术 | 维度 | 解决的问题 | 浏览器支持 |
|---|---|---|---|
| Flexbox | 一维 | 主轴对齐、均匀分布 | 2015+ |
| Grid | 二维 | 行与列同时控制 | 2017+ |
| Subgrid | 嵌套网格 | 跨层对齐 | 2023+ |
| Container Queries | 容器维度 | 组件自身响应式 | 2023+ |
第一层:Flexbox,一维的瑞士军刀
Flexbox 处理「一行(或一列)内如何排列」。典型场景是导航栏与卡片操作区:
.card__actions {
display: flex;
align-items: center;
gap: 0.5rem;
}
.card__actions .spacer {
flex: 1; /* 把后续按钮推到右侧 */
}
记住三条心法:gap 取代 margin、flex: 1 控制伸缩、min-width: 0 解除文本溢出。
第二层:Grid,真正的二维控制
当卡片列表需要同时约束行与列时,Grid 才是正解:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1.5rem;
}
auto-fit + minmax() 是响应式栅格的黄金组合:列数由容器宽度自动推导,无需媒体查询。
第三层:Subgrid,让嵌套对齐
嵌套网格最大的痛点:内层网格无法与外层轨道对齐。Subgrid 解决它——内层直接复用外层轨道:
.article-list {
display: grid;
grid-template-columns: 1fr 2fr; /* 外层轨道 */
}
.article-list > .item {
display: grid;
grid-template-rows: subgrid; /* 行轨道穿透到父级 */
grid-row: span 3;
}
这意味着一组卡片无论内容多长,日期、标题、摘要都能逐行对齐——纯 CSS,零 JS 测量。
第四层:Container Queries,组件自己的响应式
媒体查询响应的是视口,容器查询响应的是容器。同一组件放在侧栏(窄)和主内容区(宽)应呈现不同形态:
.card {
container-type: inline-size;
}
@container (min-width: 24rem) {
.card__body {
display: grid;
grid-template-columns: 8rem 1fr;
}
}
结合 container-name 还可以针对特定容器命名查询,实现真正可复用的「智能组件」。
选型决策树
- 只有一行/一列要排?→ Flexbox
- 需要同时控制行列?→ Grid
- 嵌套网格要跨层对齐?→ Subgrid
- 组件要随宿主容器变化?→ Container Queries
- 以上都不满足?→ 检查是否真的需要 CSS,
margin: auto有时就够了
小结
现代 CSS 布局不是「Grid 取代 Flexbox」的零和游戏,而是四层能力的叠加。先用对层次,再谈优化——这比追逐新特性更能稳定提升代码质量。