Flex 与 Grid 布局完整对比、原理区别、实战教学指南
Flex 与 Grid 布局完整对比、原理区别、实战教学指南
前言
Flex 与 Grid 是现代 CSS 两大核心布局体系,大部分开发者无法精准区分二者的使用场景,尤其容易混淆 normal、stretch 默认渲染规则。本文采用「文字讲解+代码实例」的教学模式,从零拆解两者核心原理、默认行为、适配场景与底层区别,解决日常开发布局错乱、属性失效的问题。
一、核心本质区别(概念+代码演示)
1. Flex 布局:一维单方向布局
Flex 属于一维布局,仅支持水平横向或垂直纵向单一方向排布,无法同时控制行和列,适合流式、自适应伸缩的布局场景。
基础一维排布代码示例:
/* 仅横向一维排布,无法控制列规整度 */
.flex-demo {
display: flex;
gap: 10px;
}
.flex-demo div {
background: #f5f7fa;
padding: 20px;
}<div class="flex-demo">
<div>内容1</div>
<div>内容2</div>
<div>内容3</div>
</div>2. Grid 布局:二维行列布局
Grid 是 CSS 唯一的二维布局体系,可同时精准定义行轨道、列轨道,统一控制所有子元素的行列位置和尺寸,适合规整、矩阵式布局场景。
基础二维行列排布代码示例:
/* 同时定义3列2行,标准二维网格 */
.grid-demo {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 80px 80px;
gap: 10px;
}
.grid-demo div {
background: #f5f7fa;
}<div class="grid-demo">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>二、核心重难点:默认属性渲染差异(实战高频坑点)
normal、stretch 是两者最大的区别,也是日常布局失效的核心原因,下面通过代码直观对比差异。
1. justify-content 默认值与生效规则
Flex 布局规则
Flex 布局下,justify-content 默认值为 normal,浏览器自动映射为 flex-start。子元素默认收缩为内容宽度,靠左排列,右侧留白。stretch 值在 Flex 中完全无效。
Flex 默认渲染效果演示:
.flex-default {
display: flex;
width: 800px;
border: 1px solid #eee;
/* 默认隐含:justify-content: normal */
}
.flex-default .item {
padding: 20px;
background: #e8f4ff;
}<div class="flex-default">
<div class="item">内容1</div>
<div class="item">内容2</div>
</div>渲染结果:两个子元素宽度由内容决定,靠左排列,容器右侧存在大量空白,不会自动拉伸填满。
Flex 实现宽度铺满的唯一方式(flex:1):
.flex-fill .item {
flex: 1; /* 唯一主轴拉伸方案 */
padding: 20px;
background: #e8f4ff;
}Grid 布局规则
Grid 布局下,justify-content 默认值为 normal,浏览器自动映射为 stretch。当网格轨道总宽度小于容器宽度时,会自动拉伸行列轨道,填满整个容器。stretch 值仅在 Grid 中生效。
Grid 默认拉伸效果演示:
.grid-default {
display: grid;
width: 800px;
grid-template-columns: 200px 200px; /* 总宽度400px,小于容器800px */
border: 1px solid #eee;
/* 默认隐含:justify-content: stretch */
}
.grid-default .item {
background: #e8f4ff;
}<div class="grid-default">
<div class="item">1</div>
<div class="item">2</div>
</div>渲染结果:两列网格自动拉伸,均分填满800px容器,无右侧留白。
2. 子元素默认尺寸行为差异
Flex 布局尺寸规则
主轴水平方向:子元素自适应内容宽度,默认不拉伸;交叉轴垂直方向:子元素默认拉伸撑满父容器高度(align-items: stretch)。
Flex 横竖尺寸差异化演示:
.flex-size {
display: flex;
width: 800px;
height: 150px;
border: 1px solid #eee;
}
.flex-size .item {
background: #e8f4ff;
margin: 0 5px;
/* 无宽度设置,自适应内容 */
/* 无高度设置,自动撑满150px */
}Grid 布局尺寸规则
Grid 主轴、交叉轴双向默认拉伸,子元素默认完全填满整个网格单元格,元素尺寸由预设的网格轨道决定,不受内容尺寸影响。
Grid 双向拉伸演示:
.grid-size {
display: grid;
width: 800px;
height: 150px;
grid-template-columns: 1fr 1fr;
border: 1px solid #eee;
}
.grid-size .item {
background: #e8f4ff;
/* 宽高自动填满单元格,无需手动设置 */
}三、Flex 布局完整特性、适用场景与代码案例
1. 核心特性
Flex 基于一维流动布局,支持元素自动伸缩、挤压、自动换行,适配数量不固定、内容自适应的布局场景,灵活性强,轻量化无冗余。
2. 实战适用场景+代码示例
适用场景:导航栏、按钮组、标签栏、水平列表、居中自适应布局、数量不固定的流式布局
通用导航栏实战模板:
.nav-flex {
display: flex;
gap: 30px;
align-items: center;
flex-wrap: wrap;
padding: 0 20px;
background: #fff;
}<div class="nav-flex">
<a href="#">首页</a>
<a href="#">分类</a>
<a href="#">关于我们</a>
</div>3. 不适用场景
无法实现行列严格对齐的矩阵布局、无法完成页面整体骨架布局、不支持跨行跨列规整排版,强行使用会出现布局错乱。
四、Grid 布局完整特性、适用场景与代码案例
1. 核心特性
Grid 基于二维网格布局,可精准定义行列轨道,支持跨行跨列、精准定位,自带拉伸铺满特性,搭配 auto-fit、minmax 可实现超强自适应规整布局。
2. 实战适用场景+代码示例
适用场景:卡片列表、商品矩阵、图片画廊、页面整体骨架布局、九宫格、行列规整的自适应布局
万能响应式卡片模板(企业级常用):
.card-grid {
display: grid;
/* 自动适配列数,最小宽度220px,剩余空间均分 */
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
}<div class="card-grid">
<div class="item">卡片1</div>
<div class="item">卡片2</div>
<div class="item">卡片3</div>
</div>3. 不适用场景
简单单行横向排布、需要元素自由挤压伸缩的轻量化场景,使用 Grid 会造成代码冗余、布局灵活性不足。
五、Flex 与 Grid 核心属性对比汇总
| 特性 | Flex 布局 | Grid 布局 |
|---|---|---|
| 布局维度 | 一维布局,仅支持单行/单列排布 | 二维布局,同时控制行、列轨道 |
| justify-content 默认值 | normal 映射为 flex-start,元素靠左收缩 | normal 映射为 stretch,网格自动拉伸铺满 |
| justify-content:stretch | 完全无效,浏览器自动忽略 | 有效,拉伸网格轨道填满容器 |
| 子元素默认尺寸 | 主轴适配内容,交叉轴拉伸撑满 | 双向默认拉伸,填满整个单元格 |
| 自适应铺满实现 | 子元素添加 flex:1 实现 | 默认原生支持,无需额外属性 |
| 跨行跨列能力 | 不支持 | 支持 grid-column、grid-row 跨行跨列 |
| 自适应换行 | 依赖 flex-wrap: wrap 实现 | 依赖 auto-fit + minmax 实现更强自适应 |
六、实战开发选型标准
1. 简单单行排布、导航、按钮组、内容需要自由伸缩挤压,优先使用 Flex。
2. 元素数量不固定、需要流式自适应换行、轻量化布局,优先使用 Flex。
3. 卡片矩阵、商品列表、图片画廊、行列规整布局,优先使用 Grid。
4. 页面整体骨架、上下左右分区、需要跨行跨列定位的布局,优先使用 Grid。
七、高频疑难问题最终解答(原理+代码佐证)
问题1:为什么 Flex 默认子元素会收缩为内容宽度?
Flex 布局中 justify-content 默认值 normal 映射为 flex-start,核心规则为「元素优先自适应内容,剩余空间留白」,无 flex:1 时不会拉伸。
问题2:justify-content:stretch 为何有时生效有时无效?
该属性仅对 Grid 网格轨道生效,用于拉伸网格填满容器;Flex 一维布局无轨道概念,无法识别该属性,永久无效。
问题3:垂直拉伸和水平拉伸的区别?
垂直拉伸由 align-items: stretch 控制,是 Flex 和 Grid 通用的交叉轴规则;水平主轴拉伸,Flex 依赖 flex:1,Grid 依赖原生 stretch 规则,二者原理完全不同。
(注:部分内容可能由 AI 生成)
版权属于:Joyber
本文链接:https://blog.qqvbc.com/default/1492.html
转载时须注明出处及本声明