Flex 与 Grid 布局完全指南

一篇讲透 display: flex 与 display: grid:从基本概念到每一个属性,全部附代码示例与效果说明,最后给出两者的对比与选型建议。


项目示例预览地址

codepen.io/editor/wang...

一、Flex 弹性布局

1.1 基本概念

Flex 是"一维"布局,只处理一个方向(主轴)上的排列。

css 复制代码
.container {
  display: flex; /* 或 inline-flex */
}

关键概念:

  • 主轴(main axis) :由 flex-direction 决定,默认水平(row),项目沿主轴排列;
  • 交叉轴(cross axis):与主轴垂直的方向;
  • 主起/主尾、交叉起/交叉尾:主轴和交叉轴的起点与终点;
  • 容器(flex container) :设置 display: flex 的元素;
  • 项目(flex item):容器的直接子元素。
ini 复制代码
主轴方向(flex-direction: row)
┌──────────────────────────────────────┐
│  [item1]  [item2]  [item3]  [item4]  │ ← 项目沿主轴排列
│                                      │
│                                      │ ← 交叉轴方向(垂直)
└──────────────────────────────────────┘

示例:

html 复制代码
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
css 复制代码
.container {
  display: flex;
  background: #f0f4ff;
  padding: 16px;
}
.item {
  background: #409eff;
  color: #fff;
  width: 80px;
  height: 80px;
  margin: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
}

1.2 容器属性(写在父元素上)

① flex-direction ------ 主轴方向

取值 效果
row(默认) 水平从左到右
row-reverse 水平从右到左
column 垂直从上到下
column-reverse 垂直从下到上
css 复制代码
.container { flex-direction: row; }      /* 默认:→ → → */
.container { flex-direction: row-reverse; } /* ← ← ← */
.container { flex-direction: column; }   /* 竖排:↓↓↓ */
.container { flex-direction: column-reverse; } /* ↑↑↑ */

注意:row-reverse/column-reverse 不只是换方向,主轴的起点终点也互换,justify-content 的对齐起点会跟着变。

② flex-wrap ------ 是否换行

取值 效果
nowrap(默认) 不换行,空间不足时项目被压缩
wrap 换行,多行排列
wrap-reverse 换行,且新行从交叉轴反向开始
css 复制代码
.container { flex-wrap: wrap; }   /* 放不下就换到下一行 */
.container { flex-wrap: nowrap; } /* 默认,强行塞一行 */
.container { flex-wrap: wrap-reverse; } /* 换行且反向 */

③ flex-flow ------ flex-direction + flex-wrap 简写

css 复制代码
.container {
  /* flex-direction: row; flex-wrap: wrap; */
  flex-flow: row wrap;
}

④ justify-content ------ 主轴方向的对齐

取值 效果
flex-start(默认) 靠主起点
flex-end 靠主终点
center 居中
space-between 两端对齐,项目间间距相等
space-around 每项两侧有相等的空间
space-evenly 所有间隙完全相等
css 复制代码
.container {
  display: flex;
  justify-content: space-between; /* 典型:导航栏左右分布 */
}
ini 复制代码
justify-content: space-between
[item1]          [item2]          [item3]

justify-content: space-evenly
   [item1]    [item2]    [item3]

⑤ align-items ------ 交叉轴方向的对齐(单行)

取值 效果
stretch(默认) 拉伸填满交叉轴高度
flex-start 靠交叉起点
flex-end 靠交叉终点
center 交叉轴居中
baseline 按文字基线对齐
css 复制代码
.container {
  display: flex;
  align-items: center; /* 最常用:垂直居中 */
}

经典实现水平垂直居中 :justify-content: center; align-items: center;

⑥ align-content ------ 多行时交叉轴的对齐

当 flex-wrap: wrap 产生多行时才生效,取值同 justify-content(外加 stretch)。

css 复制代码
.container {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between; /* 多行整体在交叉轴分布 */
  height: 400px;
}

区别:align-items 控制"每一行内项目"的对齐;align-content 控制"多行整体"的分布。单行时 align-content 无效。

⑦ gap ------ 项目间距

css 复制代码
.container {
  display: flex;
  gap: 16px;            /* 行、列间距都是 16px */
  row-gap: 12px;        /* 行间距 */
  column-gap: 8px;      /* 列间距 */
}

gap 比 margin 更好用:不影响两端、不会把间距算进 flex-basis。


1.3 项目属性(写在子元素上)

① order ------ 排列顺序

数值越小越靠前,默认 0,可为负数。

css 复制代码
.item-1 { order: 3; }
.item-2 { order: 1; }
.item-3 { order: 2; }
/* 显示顺序:item-2 → item-3 → item-1 */

② flex-grow ------ 放大比例

默认 0(不放大)。当容器有剩余空间时,按比例分配。

css 复制代码
.container { display: flex; width: 600px; }
.item { flex-grow: 1; }   /* 平均分剩余空间 */
.item-big { flex-grow: 2; } /* 占比是别的项目的 2 倍 */
css 复制代码
剩余空间 300px
[ A:flex-grow 1 ][ B:flex-grow 2 ]  → A 分 100px,B 分 200px

③ flex-shrink ------ 缩小比例

默认 1(空间不足时允许缩小)。设为 0 则不缩小(保持原尺寸,可能溢出)。

css 复制代码
.item { flex-shrink: 0; }  /* 不缩小,宽度固定 */
.item { flex-shrink: 2; }  /* 空间不足时缩小的程度更大 */

④ flex-basis ------ 初始主轴尺寸

项目在"放大/缩小之前"的基准尺寸,默认 auto(取自身 width/height)。

css 复制代码
.item { flex-basis: 200px; } /* 先按 200px 算,再参与 grow/shrink */
.item { flex-basis: 50%; }

⑤ flex ------ flex-grow flex-shrink flex-basis 简写

写法 等价 含义
flex: 1 1 1 0% 等分剩余空间(最常用)
flex: auto 1 1 auto 按内容大小 + 参与伸缩
flex: none 0 0 auto 固定尺寸,不伸缩
flex: 0 1 auto 默认 可缩小不可放大
css 复制代码
.sidebar { flex: 0 0 240px; } /* 固定 240px,不放大不缩小 */
.main { flex: 1; }            /* 占满剩余空间 */
/* 经典:侧边栏固定 + 主区自适应 */

⑥ align-self ------ 单个项目在交叉轴的对齐

覆盖容器的 align-items,取值相同。

css 复制代码
.container { align-items: center; }
.item-special { align-self: flex-end; } /* 只把这个项目放到底部 */

Flex 属性速查表:

属性 作用于 常用取值
flex-direction 容器 row / column / ...reverse
flex-wrap 容器 nowrap / wrap
flex-flow 容器 direction + wrap
justify-content 容器 center / space-between / space-evenly
align-items 容器 center / stretch / baseline
align-content 容器 多行分布
gap 容器 间距
order 项目 排列顺序
flex-grow 项目 放大比例
flex-shrink 项目 缩小比例
flex-basis 项目 初始尺寸
flex 项目 三合一简写
align-self 项目 单项目对齐

二、CSS Grid 网格布局

2.1 基本概念

Grid 是"二维"布局,同时处理行和列。

css 复制代码
.container {
  display: grid; /* 或 inline-grid */
}

关键概念:

  • 网格线(grid line):划分网格的线,行线/列线;
  • 网格轨道(track):两条相邻线之间的行/列;
  • 网格单元(cell):行与列交叉的最小单位;
  • 网格区域(area):一个或多个单元格组成的矩形区域。
makefile 复制代码
列线: 1        2       3        4
      │  100px │ 1fr   │ 1fr    │
行线 1┌────────┬────────┬────────┐
     │  cell  │  cell  │  cell  │
行线 2├────────┼────────┼────────┤
     │  cell  │  cell  │  cell  │
行线 3└────────┴────────┴────────┘

示例:

html 复制代码
<div class="grid">
  <div class="box">A</div>
  <div class="box">B</div>
  <div class="box">C</div>
  <div class="box">D</div>
</div>
css 复制代码
.grid {
  display: grid;
  grid-template-columns: 100px 1fr 1fr; /* 3 列:固定 + 两列自适应 */
  grid-template-rows: 80px 80px;        /* 2 行 */
  gap: 12px;
}
.box {
  background: #409eff;
  color: #fff;
  display: grid;
  place-items: center; /* 单元格内居中 */
}

2.2 容器属性(写在父元素上)

① grid-template-columns / grid-template-rows ------ 定义轨道

支持多种单位:

css 复制代码
/* 固定值 */
.grid { grid-template-columns: 100px 200px 100px; }

/* 百分比 */
.grid { grid-template-columns: 25% 25% 50%; }

/* fr(fraction 分数单位):按比例瓜分剩余空间 */
.grid { grid-template-columns: 1fr 2fr 1fr; } /* 1:2:1 三列 */

/* repeat():重复 */
.grid { grid-template-columns: repeat(3, 1fr); } /* 等同 1fr 1fr 1fr */

/* minmax():最小-最大约束 */
.grid { grid-template-columns: minmax(200px, 1fr) 1fr; }
/* 第一列至少 200px,最多占满剩余 */

/* auto:按内容 */
.grid { grid-template-columns: auto 1fr; }
css 复制代码
/* 行同理 */
.grid {
  grid-template-rows: 100px auto 1fr; /* 头 / 内容自适应 / 尾部占满 */
}

auto-fill 与 auto-fit ------ 自动填充:

css 复制代码
.grid {
  display: grid;
  /* 每列至少 200px,能放几列放几列(自适应列数) */
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  /* auto-fit 与 auto-fill 区别:项目少时 auto-fit 会把空轨道塌陷合并 */
}

② grid-template-areas ------ 区域命名布局

css 复制代码
.page {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: 60px 1fr 60px;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer";
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer  { grid-area: footer; }
css 复制代码
┌──────────┬──────────┐
│ header   │ header   │
├──────────┼──────────┤
│ sidebar  │ content  │
├──────────┼──────────┤
│ footer   │ footer   │
└──────────┴──────────┘

用 .(点)表示空单元格:grid-template-areas: "a . b";

③ gap ------ 行列间距

css 复制代码
.grid {
  display: grid;
  gap: 16px;          /* 行列统一 */
  row-gap: 12px;      /* 行间距 */
  column-gap: 8px;    /* 列间距 */
}

④ grid-auto-flow ------ 项目自动放置规则

取值 效果
row(默认) 按行依次放置,放满一行换下一行
column 按列依次放置
dense 回填前面留下的空洞(可与 row/column 组合:row dense)
css 复制代码
.grid { grid-auto-flow: column; }  /* 纵向排列 */
.grid { grid-auto-flow: row dense; } /* 尽量紧凑,回填空洞 */

⑤ grid-auto-rows / grid-auto-columns ------ 隐式轨道大小

显式轨道用 grid-template-* 定义;放不下的项目会创建"隐式轨道",用这组属性控制其大小。

css 复制代码
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 80px;           /* 新增行的默认高度 */
  grid-auto-columns: 100px;       /* 新增列的默认宽度 */
}

⑥ justify-items / align-items ------ 项目在单元格内的对齐

取值 效果
stretch(默认) 拉伸填满单元格
start 起点(左/上)
end 终点(右/下)
center 居中
css 复制代码
.grid {
  justify-items: center;  /* 水平居中 */
  align-items: center;    /* 垂直居中 */
  /* 简写 */
  place-items: center;    /* = justify-items + align-items */
}

⑦ justify-content / align-content ------ 整个网格在容器内的对齐

当网格总尺寸小于容器(例如用固定像素定义轨道)时生效。

css 复制代码
.grid {
  display: grid;
  grid-template-columns: 100px 100px; /* 总宽 200px < 容器 */
  justify-content: center;   /* 网格整体水平居中 */
  align-content: space-between; /* 网格整体垂直分布 */
  /* 简写 */
  place-content: center;
}

取值:start / end / center / stretch / space-between / space-around / space-evenly。

⑧ grid-template ------ 简写

css 复制代码
.grid {
  /* grid-template-rows / grid-template-columns / grid-template-areas */
  grid-template:
    "header header" 60px
    "sidebar content" 1fr
    "footer footer" 60px
    / 200px 1fr;
}

2.3 项目属性(写在子元素上)

① grid-column / grid-row ------ 按网格线定位

css 复制代码
.item {
  /* 从第 1 列线到第 3 列线(占 2 列) */
  grid-column: 1 / 3;
  /* 从第 2 行线开始,跨越 2 行 */
  grid-row: 2 / span 2;
}

常用写法:

css 复制代码
.item { grid-column: 1 / 3; }      /* 起线 / 止线 */
.item { grid-column: 1 / -1; }     /* -1 表示最后一条线,即占满整行 */
.item { grid-column: span 2; }     /* 跨越 2 列(不指定起线) */
.item { grid-column: 2; }          /* 单列简写 */
.item { grid-column: 1 / span 2; } /* 从线 1 开始跨 2 列 */

示例:一列跨两列:

css 复制代码
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.item-wide { grid-column: 1 / 3; } /* 占第 1、2 列 */

② grid-area ------ 区域定位

两种用法:用 grid-template-areas 定义的名字,或四线定位。

css 复制代码
/* 用法一:区域名(配合 grid-template-areas) */
.item { grid-area: sidebar; }

/* 用法二:四条网格线 row-start / column-start / row-end / column-end */
.item {
  grid-area: 1 / 1 / 3 / 3;
  /* 从第1行第1列 到 第3行第3列(占 2x2) */
}

③ justify-self / align-self / place-self ------ 单个项目在单元格内对齐

css 复制代码
.item {
  justify-self: center; /* 水平居中(覆盖 justify-items) */
  align-self: end;      /* 垂直靠下 */
  place-self: center;   /* 简写,单元格内居中 */
}

Grid 属性速查表:

属性 作用于 作用
grid-template-columns/rows 容器 定义轨道(fr / repeat / minmax)
grid-template-areas 容器 区域命名布局
gap 容器 行列间距
grid-auto-flow 容器 自动放置规则(row/column/dense)
grid-auto-rows/columns 容器 隐式轨道大小
justify/align/place-items 容器 项目在单元格内对齐
justify/align/place-content 容器 网格整体对齐
grid-column/row 项目 按线定位、跨越
grid-area 项目 区域定位 / 四线定位
justify/align/place-self 项目 单项目对齐

三、Flex vs Grid:对比与选型

3.1 核心区别

对比项 Flex Grid
维度 一维(一个方向) 二维(行 + 列)
设计思想 内容驱动(项目伸缩填满) 布局驱动(先画网格再放内容)
擅长 单行/单列排列、对齐、居中等 页面骨架、规则二维布局
跨行跨列 不支持(同一轴线) 原生支持(span / grid-area)
列数 由内容决定 由轨道定义决定

3.2 典型选型建议

优先用 Flex:

css 复制代码
/* 导航栏:一行水平分布 */
.nav { display: flex; justify-content: space-between; align-items: center; }

/* 按钮组 / 图标行 */
.toolbar { display: flex; gap: 8px; }

/* 垂直居中 */
.center { display: flex; justify-content: center; align-items: center; }

/* 固定侧栏 + 自适应主区 */
.sidebar { flex: 0 0 240px; }
.main { flex: 1; }

优先用 Grid:

css 复制代码
/* 页面整体骨架:二维区域划分 */
.page {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer";
}

/* 商品卡片网格:自动响应式列数 */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}

/* 九宫格 / 表格类布局 */
.board {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
  gap: 8px;
}

3.3 两者混用(最常用实践)

用 Grid 做整体骨架 ,用 Flex 做局部对齐:

css 复制代码
.page {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    "header header"
    "sidebar content";
  height: 100vh;
}
.header {
  grid-area: header;
  display: flex;               /* Grid 里再用 Flex */
  justify-content: space-between;
  align-items: center;
}
.content {
  grid-area: content;
  display: grid;               /* 内容区再嵌套 Grid */
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}

3.4 常见面试追问

Q:Flex 和 Grid 能互相替代吗? 不能完全替代。Flex 擅长单维度的弹性排列与对齐;Grid 擅长二维的规则划分。复杂布局常两者组合使用。

Q:flex: 1 和 1fr 的区别?

  • flex: 1 是 flex-grow: 1,针对剩余空间按比例分配;
  • 1fr 是网格分数单位,针对整条轨道按比例分配。 两者都能实现自适应,但作用模型不同。

Q:什么时候用 place-items 什么时候用 place-content?

  • place-items 控制项目在单元格内的位置;
  • place-content 控制整个网格在容器中的位置。

收藏这份指南,配合动手敲代码练习:先掌握 Flex 的一维思维,再掌握 Grid 的二维思维,两者结合基本能覆盖前端 99% 的布局场景。

相关推荐
程序员大阳14 小时前
副队长CSS教程(29)–CSS Grid 实战:实现通用图文混排布局
前端·css·grid·图文混排
song50117 小时前
React Native for OpenHarmony 实战:三方库 react-native-popup-menu 的鸿蒙化适配指南
css·深度学习·react native·react.js·transformer·harmonyos
溪语流沙1 天前
【每天一个CSS | Day19】流光文字与一笔写成的手写签名
前端·javascript·css
一水鉴天2 天前
统一对象拓扑(UOT)设计全链定稿:从三件事分离到三继承 之1 20261010(豆包“查看聊天内容”继续)
前端·css
song5012 天前
React Native for OpenHarmony 实战:三方库 react-native-css-transformer 的鸿蒙化适配指南
css·人工智能·深度学习·react native·transformer
思码梁田3 天前
CSS transform 转换详解:translate、rotate、scale、skew 与 3D 变换一次讲清
前端·css·transform·skew·scale·translate·rotate
三天不学习3 天前
Tailwind CSS 快速入门(2026 版):从 v4 零配置上手,到「该不该用、怎么用好」的选型实战
前端·css·tailwind
htzyl2063 天前
前端阶梯——第九章、颜色、文本与背景
前端·css
htzyl2063 天前
前端阶梯——第八章、CSS入门与选择器
前端·css
传人5 天前
页面中心圆圈放大效果如何写
前端·css