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 生成)

标签: none

添加新评论