布局工具的选择
现代 CSS 提供了三种强大的布局工具。选择哪种取决于你的布局需求:
- Flexbox —— 一维布局(行或列),适合组件内部对齐和分配空间
- Grid —— 二维布局(行+列),适合页面整体布局和复杂网格
- Container Queries —— 基于容器尺寸响应,适合真正的组件级响应式
Flexbox 进阶技巧
大多数人知道 Flexbox 的基础用法,但这些技巧能让你的布局更灵活。
完美的居中方案
/* 万能居中 */
.center-everything {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* 文本和行内元素的垂直居中 */
.card {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
}
/* 圣杯布局:固定侧边栏 + 自适应主内容 */
.layout {
display: flex;
min-height: 100vh;
}
.sidebar { width: 260px; flex-shrink: 0; }
.main { flex: 1; } /* 自动填满剩余空间 */
flex-wrap 与自动换行
/* 响应式标签云 —— 自动换行 */
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
/* 底部对齐的卡片列表 */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card {
flex: 1 1 300px; /* 最小 300px,可增长 */
display: flex;
flex-direction: column;
}
.card-footer {
margin-top: auto; /* 推到底部 */
}
order 属性控制视觉顺序
/* 移动端:内容优先,侧边栏下方 */
@media (max-width: 768px) {
.layout { flex-direction: column; }
.main { order: -1; } /* 主内容移到最前面 */
.sidebar { order: 1; }
}
CSS Grid 实战
Grid 是 CSS 中最强大的布局系统,特别适合构建复杂的页面布局。
自适应网格(Auto-Fit / Auto-Fill)
/* 自动适应列数的卡片网格 */
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
/* auto-fit vs auto-fill 的区别:
auto-fit: 空轨道会被折叠,卡片会自动拉伸填满
auto-fill: 空轨道保留,卡片保持原始大小 */
命名区域布局
/* 用命名区域定义页面布局 —— 直观且易维护 */
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
grid-template-columns: 240px 1fr 200px;
grid-template-rows: 64px 1fr auto;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
@media (max-width: 1024px) {
.page-layout {
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 200px 1fr;
}
.aside { display: none; }
}
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"content"
"footer";
grid-template-columns: 1fr;
}
.sidebar { display: none; }
}
Subgrid —— 子元素对齐父网格
/* 卡片内容对齐:标题、描述、按钮在不同卡片间对齐 */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.card {
display: grid;
grid-template-rows: subgrid; /* 继承父网格的行定义 */
grid-row: span 3; /* 占 3 行:标题、描述、按钮 */
}
/* 确保所有卡片的标题区域等高,描述区域等高,按钮底部对齐 */
Container Queries —— 组件级响应式
传统的 @media 查询基于视口宽度,但组件可能被放在不同宽度的容器中。Container Queries 让组件根据自身容器的尺寸来调整样式。
/* 第一步:声明容器 */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
/* 第二步:基于容器宽度写样式 */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1.5rem;
}
.card-image {
aspect-ratio: 1;
border-radius: 12px 0 0 12px;
}
}
@container card (min-width: 600px) {
.card {
grid-template-columns: 240px 1fr;
padding: 2rem;
}
.card-title {
font-size: 1.5rem;
}
}
@container card (max-width: 399px) {
.card {
padding: 1rem;
}
.card-title {
font-size: 1rem;
}
}
Container Query 单位
/* 容器相对单位 */
.card-title {
/* cqi = 容器内联尺寸的 1% */
font-size: clamp(1rem, 4cqi, 2rem);
/* cqb = 容器块尺寸的 1% */
line-height: clamp(1.4, 5cqb, 1.8);
}
/* 实用场景:仪表盘小组件在不同宽度下自动调整 */
.stat-card {
container-type: inline-size;
}
.stat-value {
font-size: clamp(1.5rem, 8cqi, 3rem);
}
.stat-label {
font-size: clamp(0.75rem, 3cqi, 1rem);
}
实用布局模式合集
等高卡片布局
/* Grid 方案:天然等高 */
.equal-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
align-items: start;
}
/* Flex 方案:通过 stretch 实现 */
.equal-cards-flex {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.equal-cards-flex > * {
flex: 1 1 250px;
align-self: stretch;
}
粘性 Footer 布局
/* Grid 方案 */
body {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* Flex 方案 */
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main { flex: 1; }
/* 最现代方案 */
body {
min-height: 100vh;
min-height: 100dvh; /* 动态视口高度,处理移动端地址栏 */
display: grid;
grid-template-rows: auto 1fr auto;
}
全宽横幅中的居中内容
/* 不需要额外的 wrapper div */
.hero-section {
display: grid;
grid-template-columns:
1fr
min(90%, 1200px)
1fr;
}
.hero-section > * {
grid-column: 2;
}
/* 全宽背景但内容居中 —— 直接把背景设在 section 上 */
.hero-section > .full-bleed {
grid-column: 1 / -1; /* 占满所有列 */
}
CSS Grid vs Flexbox 选择指南
| 场景 | 推荐 | 原因 |
|---|---|---|
| 导航栏 | Flexbox | 一维水平排列,对齐简单 |
| 页面整体布局 | Grid | 二维布局,区域定义清晰 |
| 卡片网格 | Grid | auto-fit 自动列数,天然等高 |
| 表单标签+输入框 | Grid | 对齐标签和输入框的宽度 |
| 居中单个元素 | Flexbox | 两行代码搞定 |
| 瀑布流/Pinterest | Grid | grid-row: span N 实现不等高 |
| 按钮组 | Flexbox | 间距和对齐灵活 |
总结
现代 CSS 布局已经非常强大,Grid 和 Flexbox 的组合可以覆盖几乎所有布局需求。Container Queries 的出现更是让组件级响应式成为现实。建议:
- 页面整体布局用 Grid
- 组件内部对齐用 Flexbox
- 组件需要在不同容器宽度下适配时用 Container Queries
- 善用
gap属性替代 margin,代码更简洁 - 使用
min()、max()、clamp()实现流式响应