在前端开发中,"Flexbox 还是 Grid?"是一个反复出现的问题。两者都是 CSS 布局系统的核心工具,但它们的适用场景有明确的差异。本文从实际案例出发,梳理了选择标准。
本质区别:一维 vs 二维
Flexbox 和 Grid 最根本的区别在于布局维度:
- Flexbox 是一维布局系统。它沿着一个方向(主轴)排列元素,另一个方向(交叉轴)只做对齐和拉伸。适合处理"一排元素"或"一列元素"的场景。
- Grid 是二维布局系统。它同时控制行和列,元素可以跨越多个网格单元。适合需要同时管理横向和纵向排列的场景。
这个区别看似简单,但在实际决策中,许多人会忽略一个关键点:如果布局在某个维度上是固定的,在另一个维度上是动态的,Flexbox 通常更合适;如果两个维度都需要精确控制,Grid 是更好的选择。
Flexbox 的最佳场景
以下场景推荐使用 Flexbox:
- 导航栏:水平排列的菜单项,响应式换行。Flexbox 的
justify-content和align-items可以优雅地处理对齐。 - 卡片内容排列:卡片内的标题、描述、按钮垂直排列,间距统一。Flexbox 的
gap属性使间距管理变得简单。 - 表单行:标签和输入框水平对齐,表单行垂直堆叠。
- 居中:单个元素在容器中居中对齐——Flexbox 用
display: flex; justify-content: center; align-items: center;三行代码就能搞定。
/* Flexbox 导航栏 */
.nav {{
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}}
Grid 的最佳场景
以下场景推荐使用 Grid:
- 整体页面布局:页头、侧边栏、主内容区、页脚——二维的页面骨架天然适合 Grid。
- 照片画廊:等宽或不等宽的网格排列,元素可以跨行跨列。
- 仪表盘:多个面板在二维空间中的排列,面板可以有不同的尺寸。
- 表单布局:复杂的多列表单,标签和输入框在网格中对齐。
/* Grid 页面布局 */
.page {{
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}}
选择决策表
| 判断标准 | 选 Flexbox | 选 Grid |
|---|---|---|
| 内容驱动 vs 布局驱动 | 内容决定尺寸 | 布局决定尺寸 |
| 排列维度 | 单方向排列 | 双方向精确控制 |
| 对齐需求 | 分布/居中为主 | 网格对齐为主 |
| 响应式策略 | flex-wrap 自然换行 | 媒体查询改变列数 |
| 子元素尺寸 | 不固定,弹性伸缩 | 按轨道尺寸分配 |
实际建议
在实践中,两者经常混合使用——页面用 Grid 做骨架,组件内部用 Flexbox 做细节排列。例如,照片画廊的整体网格用 Grid,每个照片卡片内部的内容排列用 Flexbox。不必拘泥于"只能选一个"的思维,它们是互补的工具,而非竞争对手。
一个常见的反模式是:在只需要一维排列的地方使用 Grid(比如导航栏),或者在需要精确控制二维排列的地方使用多个嵌套的 Flexbox。前者过度设计,后者会让代码变得复杂且难以维护。选择合适的工具,代码会自然简洁。