CSS Grid vs Flexbox:2026年Web布局完全指南
CSS Grid vs Flexbox:2026年Web布局完全指南
CSS Grid和Flexbox如何选择?通过实战代码示例了解区别、用途和组合技巧。
2026年3月17日4分钟阅读
CSS布局的演进
CSS布局经历了漫长的演进:从最初的float和position,到display: table,再到如今的Flexbox和Grid。2026年,这两种现代布局系统已经得到所有主流浏览器的完全支持,成为前端开发的基石。
但很多开发者对这两个工具感到困惑:什么时候用Flexbox?什么时候用Grid?能不能混用?本文将清晰回答这些问题,并提供大量实战代码示例。
核心区别:一维 vs 二维
理解两者最关键的一点:
- Flexbox(弹性布局):一维布局工具,沿单一轴(横轴或纵轴)排列元素
- CSS Grid(网格布局):二维布局工具,同时控制行和列
| 维度 | Flexbox | CSS Grid |
|---|---|---|
| 布局维度 | 一维(行或列) | 二维(行和列) |
| 设计方向 | 内容驱动(从内向外) | 布局驱动(从外向内) |
| 对齐控制 | 强大的轴对齐 | 精确的行列定位 |
| 响应式 | 自然弹性 | 精确控制 |
| 浏览器支持 | 极佳 | 极佳 |
| 学习难度 | 相对简单 | 稍复杂 |
Flexbox:掌握弹性布局
基础概念
.container {
display: flex;
flex-direction: row; /* 主轴方向:row | row-reverse | column | column-reverse */
flex-wrap: wrap; /* 换行:nowrap | wrap | wrap-reverse */
justify-content: space-between; /* 主轴对齐 */
align-items: center; /* 交叉轴对齐 */
gap: 16px; /* 间距 */
}
实战示例1:导航栏
<nav class="navbar">
<div class="logo">ToolBox Hub</div>
<ul class="nav-links">
<li><a href="#">首页</a></li>
<li><a href="#">工具</a></li>
<li><a href="#">博客</a></li>
</ul>
<button class="cta-btn">开始使用</button>
</nav>
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
height: 64px;
background: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.nav-links {
display: flex;
list-style: none;
gap: 32px;
margin: 0;
padding: 0;
}
/* 响应式:移动端隐藏链接 */
@media (max-width: 768px) {
.nav-links {
display: none;
}
}
实战示例2:卡片组件
.card {
display: flex;
flex-direction: column;
border-radius: 8px;
border: 1px solid #e5e7eb;
overflow: hidden;
}
.card-body {
display: flex;
flex-direction: column;
flex: 1; /* 占据剩余空间 */
padding: 16px;
}
.card-title {
font-size: 1.125rem;
font-weight: 600;
margin-bottom: 8px;
}
.card-description {
flex: 1; /* 推动按钮到底部 */
color: #6b7280;
margin-bottom: 16px;
}
.card-action {
margin-top: auto; /* 始终在底部 */
}
Flexbox子元素属性
.flex-item {
flex-grow: 1; /* 增长比例,默认0 */
flex-shrink: 1; /* 收缩比例,默认1 */
flex-basis: auto; /* 初始大小 */
/* 简写 */
flex: 1; /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
flex: 0 0 200px; /* 固定宽度200px,不增长不收缩 */
align-self: flex-start; /* 覆盖容器的align-items */
order: 2; /* 排序(默认0) */
}
CSS Grid:掌握网格布局
基础概念
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3列等宽 */
grid-template-rows: auto; /* 行高自动 */
gap: 24px; /* 行列间距 */
}
实战示例1:经典博客布局
<div class="blog-layout">
<header class="site-header">网站头部</header>
<aside class="sidebar">侧边栏</aside>
<main class="main-content">主内容区</main>
<footer class="site-footer">页脚</footer>
</div>
.blog-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 260px 1fr;
grid-template-rows: 64px 1fr 80px;
min-height: 100vh;
gap: 0;
}
.site-header { grid-area: header; background: #1f2937; color: white; }
.sidebar { grid-area: sidebar; background: #f9fafb; border-right: 1px solid #e5e7eb; }
.main-content { grid-area: main; padding: 24px; }
.site-footer { grid-area: footer; background: #374151; color: white; }
/* 响应式:移动端单列 */
@media (max-width: 768px) {
.blog-layout {
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
}
实战示例2:响应式图片画廊
.gallery {
display: grid;
/* 自动填充列,每列最小200px,最大1fr */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
}
.gallery-item {
aspect-ratio: 1; /* 正方形 */
border-radius: 8px;
overflow: hidden;
}
.gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s;
}
.gallery-item:hover img {
transform: scale(1.05);
}
/* 特定卡片占据2列 */
.gallery-item.featured {
grid-column: span 2;
grid-row: span 2;
}
实战示例3:仪表板布局
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, auto);
gap: 20px;
padding: 24px;
}
/* 统计卡片:4个并排 */
.stat-card {
/* 默认占1列 */
}
/* 主图表:占2列2行 */
.main-chart {
grid-column: span 2;
grid-row: span 2;
}
/* 次要图表:占1列2行 */
.secondary-chart {
grid-row: span 2;
}
/* 数据表格:占满底部 */
.data-table {
grid-column: 1 / -1; /* 从第1列到最后一列 */
}
组合使用:Flexbox + Grid
最强大的布局方式往往是两者的结合:
/* 外层用Grid定义页面布局 */
.page {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* 内层用Flexbox处理组件内布局 */
.card-list {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 280px; /* 弹性宽度,最小280px */
display: flex;
flex-direction: column;
}
决策指南
使用Flexbox的情况
- 导航栏(水平排列链接)
- 按钮组和操作区域
- 垂直/水平居中单个元素
- 卡片内部布局(垂直方向)
- 标签(Chip)列表
- 表单元素对齐
使用Grid的情况
- 整体页面布局(Header/Sidebar/Main/Footer)
- 卡片网格(产品列表、图片画廊)
- 仪表板布局
- 需要精确对齐行和列的场景
- 复杂的杂志风格布局
- 响应式网格
常见布局解决方案
完美居中
/* Flexbox居中 */
.center-flex {
display: flex;
justify-content: center;
align-items: center;
}
/* Grid居中 */
.center-grid {
display: grid;
place-items: center; /* 等同于 align-items + justify-items */
}
等高卡片
/* 不管内容多少,卡片高度一致 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
align-items: stretch; /* 默认值,拉伸到相同高度 */
}
Holy Grail布局(圣杯布局)
.holy-grail {
display: grid;
grid-template:
"header" auto
"nav main aside" 1fr
"footer" auto
/ 200px 1fr 200px;
min-height: 100vh;
}
总结
Flexbox和Grid不是竞争关系,而是互补关系:
- Flexbox擅长:一维排列、内容驱动的弹性布局、对齐单行或单列元素
- Grid擅长:二维布局、从外向内的结构定义、复杂的页面级布局
实际开发中,最佳实践是在外层使用Grid定义整体结构,在组件内部使用Flexbox处理细节对齐。熟练掌握这两个工具,你就能优雅地实现任何Web布局,告别float: left和负边距的时代。