一文讲清Flex与Grid
一文讲清 Flex 与 Grid
先记住核心结论: ✅ Flex(弹性布局):一维布局 —— 只有一条主轴,要么横着排、要么竖着排 ✅ Grid(网格布局):二维布局 —— 同时控制「行 + 列」,平面网格
通俗比喻: Flex = 一排货架(只能沿着一个方向摆放商品,换行只是自动折行,没有固定列线) Grid = 棋盘 / 表格(天生多行多列,横纵两条线同时管控)
一、Flex 弹性布局 display:flex
1. 基础规则
给父盒子设置:
.box {
display: flex;
/* 默认:横向排列 */
flex-direction: row;
}子元素自动沿着主轴排列。 主轴两个方向:
row(默认):水平横向column:垂直纵向
2. 关键特性
单一方向:只能选横 或 竖,不能同时自由控制行列
子元素默认不换行,空间不够会挤压宽度
flex-wrap: wrap; /* 开启自动换行 */
⚠️重点:换行后虽然看起来有多行,依然不是二维布局! Flex 换行只是「多条一维队列」,没法统一控制每一列对齐、固定列宽。
常用对齐(新手高频)
/* 主轴对齐(横向/纵向,看flex-direction) */ justify-content: center; /* 交叉轴对齐(和主轴垂直的方向) */ align-items: center;
3. Flex 适合做什么
? 线性组件导航栏、按钮组、水平卡片列表、垂直菜单栏、居中盒子、底部工具栏、页面水平居中。
示例场景:顶部导航栏,一排链接,均匀分布。
❌ Flex 短板
想实现「整齐多行多列,每一列宽度强制统一」,用 Flex 很麻烦,要大量计算。
二、Grid 网格布局 display:grid
1. 基础规则
父盒子开启网格:
.box {
display: grid;
/* 定义3列,每列均分 */
grid-template-columns: 1fr 1fr 1fr;
/* 定义2行,高度自动 */
grid-template-rows: auto auto;
gap: 10px; /* 格子间距(替代margin,更干净) */
}1fr = 剩余空间一份(非常好用,等价均分)
2. 关键特性
真正二维:同时拥有横线(行)、竖线(列),整张页面是一张网格
天生支持固定行列,子元素自动落入格子
可以指定某个子元素跨多行、跨多列
.item {
grid-column: span 2; /* 这个格子占2列宽度 */
}对齐方式和 Flex 类似,但作用在网格上
justify-items: center; /* 水平 */ align-items: center; /* 垂直 */
3. Grid 适合做什么
? 平面多行多列布局商品列表、图片画廊、后台管理页面布局、卡片网格、复杂页面整体排版。
❌ Grid 短板
单纯一行导航栏,用 Grid 属于杀鸡用牛刀;简单线性排布代码比 flex 啰嗦。
三、核心直观对比表
| 特性 | Flex(display:flex) | Grid(display:grid) |
|---|---|---|
| 维度 | 一维:横 或 竖 | 二维:行 + 列同时控制 |
| 思考方式 | 沿着一条线摆放元素 | 在棋盘格子里摆放元素 |
| 换行 | wrap换行只是多条一维队列 | 原生定义行列结构 |
| 典型场景 | 导航、按钮组、单行列表、居中 | 商品网格、整体页面布局、画廊 |
| 跨区域 | 很难实现元素跨多行多列 | 原生支持跨列、跨行 |
四、新手最简单选择法则(直接照抄)
元素只需要排成一排 / 一列 → 用 Flex导航、头部菜单、底部按钮、垂直表单条目、水平居中。
需要整齐多行多列,像表格/画廊 → 优先 Grid商品列表、图片墙、后台dashboard布局。
实战最佳方案:混合使用大页面框架用 Grid 划分头部、侧边栏、主体; 区块内部一排按钮、文字排版再用 Flex。
五、常见新手误区澄清
误区1:Flex 开启 wrap 多行,就是二维布局
❌ 错! flex-wrap 换行之后,每一行是独立队列。 比如第一行3个元素、第二行2个元素,无法强制第二行第一个元素和上一行第一列对齐成规整网格,很难实现均等列。
误区2:能用 Grid 就全部用 Grid
❌ 没必要。单行导航用 flex 代码更少、更简洁。
误区3:Grid 和 table 一样
❌ table 是表格语义,有很多默认样式限制;Grid 是纯粹布局,自由拖拽元素位置,不影响 HTML 语义。
六、极简示例代码可直接复制测试
Flex 单行导航
<style>
.nav {
display: flex;
gap: 16px;
}
</style>
<div class="nav">
<a>首页</a>
<a>产品</a>
<a>关于我们</a>
</div>Grid 三列商品网格
<style>
.goods {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
}
</style>
<div class="goods">
<div>商品1</div>
<div>商品2</div>
<div>商品3</div>
<div>商品4</div>
<div>商品5</div>
</div>如果你想要,我可以再出一套练习题,判断每种场景该选 flex 还是 grid,帮你巩固区分!