前言
2025 年了,还在用 float 和 position: absolute 做布局?本文覆盖 Flexbox、Grid 和 Container Queries 三大现代布局方案,从基础到进阶,30 分钟掌握 CSS 布局的全貌。
一、Flexbox:一维弹性的王者
1.1 核心属性速查
/* 容器属性 */
.container {
display: flex;
flex-direction: row | column; /* 主轴方向 */
justify-content: flex-start | center | space-between | space-around;
align-items: stretch | center | flex-start | flex-end;
flex-wrap: nowrap | wrap; /* 换行 */
gap: 16px; /* 间距(推荐替代 margin)*/
}
/* 子项属性 */
.item {
flex: 1; /* flex-grow | flex-shrink | flex-basis 简写 */
align-self: center; /* 单独覆盖 align-items */
order: 1; /* 排序(越小越靠前)*/
}
1.2 经典布局:圣杯导航栏
<nav class="navbar">
<div class="nav-left">
<img src="logo.svg" alt="Logo" />
</div>
<div class="nav-center">
<a href="#">首页</a>
<a href="#">博客</a>
<a href="#">关于</a>
</div>
<div class="nav-right">
<button>登录</button>
</div>
</nav>
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
}
/* 自动左右撑开,中间居中 */
/* nav-left 靠左,nav-center 居中,nav-right 靠右 */
1.3 高级技巧:响应式卡片网格(无需 Grid)
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 300px; /* grow shrink basis */
/* 自动适配:最小 300px,空间够就平铺,不够就换行 */
min-width: 0; /* 防止内容溢出 */
}
二、CSS Grid:二维布局的终极方案
2.1 核心概念
.grid-container {
display: grid;
/* 三列:200px | 自适应填满 | 200px */
grid-template-columns: 200px 1fr 200px;
/* 行高:首行 auto 高度,其余最小 100px */
grid-template-rows: auto;
grid-auto-rows: minmax(100px, auto);
gap: 16px;
}
2.2 实战:仪表盘布局
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
gap: 16px;
grid-template-areas:
"stats stats stats sidebar"
"chart1 chart1 chart2 sidebar"
"table table table sidebar";
}
.stats { grid-area: stats; }
.chart-1 { grid-area: chart1; }
.chart-2 { grid-area: chart2; }
.table { grid-area: table; }
.sidebar { grid-area: sidebar; }
/* 响应式:小屏变单列 */
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
grid-template-areas:
"stats"
"chart1"
"chart2"
"table"
"sidebar";
}
}
2.3 Grid 实用技巧:自适应列数
/* 无需媒体查询,自动根据容器宽度增减列数 */
.grid-auto {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
/* auto-fill: 尽可能多放 → 适合卡片列表 */
/* auto-fit: 拉伸填满 → 适合居中少量元素 */
/* 进阶:列数范围控制 */
.grid-bounded {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr));
gap: 16px;
}
三、Container Queries:组件级响应式的未来
传统 @media 查询只能基于视口宽度响应。Container Queries 让你基于父容器宽度响应——真正的组件级响应式。
/* 1. 定义容器 */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
/* 2. 基于容器宽度响应 */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 150px 1fr;
gap: 16px;
}
.card-image { border-radius: 12px 0 0 12px; }
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
.card-image { border-radius: 12px 12px 0 0; }
}
<!-- 无论放在哪里,卡片根据自身容器自适应 -->
<div class="sidebar"> <!-- 300px 宽 → 卡片竖排 -->
<div class="card-wrapper">
<div class="card">...</div>
</div>
</div>
<div class="main"> <!-- 700px 宽 → 卡片横排 -->
<div class="card-wrapper">
<div class="card">...</div>
</div>
</div>
四、Flexbox vs Grid 选型指南
| 场景 | 推荐 | 理由 |
|---|---|---|
| 导航栏 / 工具栏 | Flexbox | 一维排列,内容驱动宽度 |
| 整体页面布局 | Grid | 行+列同时控制,grid-template-areas 语义化 |
| 卡片列表 | 都可以 | 内容不自知宽度 → Flex;需要严格行列对齐 → Grid |
| 仪表盘 / 后台 | Grid | 二维精确控制,命名区域 |
| 居中单个元素 | Flexbox | 3 行代码: display:flex; align-items:center; justify-content:center |
| 响应式组件 | Container Queries | 基于容器而非视口,真正的组件化 |
五、浏览器兼容性
| 特性 | Chrome | Safari | Firefox |
|---|---|---|---|
| Flexbox | 29+ | 9+ | 28+ |
| Grid (基础) | 57+ | 10.1+ | 52+ |
| Subgrid | 117+ | 16+ | 71+ |
| Container Queries | 105+ | 16+ | 110+ |
| gap in Flexbox | 84+ | 14.1+ | 63+ |
学习建议:先用 Flexbox 解决 80% 的布局问题,Grid 处理复杂页面结构,Container Queries 让组件真正独立。三者各司其职,不必非此即彼。Grid 也可以嵌套 Flexbox,反之亦然。