海川的日志

Flex布局精通

作者:海川,发表于:2026年1月24日 07:30:00

全面掌握Flex布局

一、Flex 基础概念

1. 什么是 Flex?

  • Flexible Box Layout,灵活的盒子布局
  • 是CSS3提供的一种强大的一维布局方案
  • 相比浮动、定位等传统布局方式,Flex具有更好的灵活性和易用性
  • 广泛应用于现代Web开发中,特别是响应式设计

2. Flex 相比传统布局的优势

  • ✅ 自适应性强,能自动调整子元素宽度/高度来填充容器
  • ✅ 对齐方式灵活,轻松实现水平、竖直、中心对齐等
  • ✅ 排序方便,可通过order属性改变元素顺序,不影响HTML结构
  • ✅ 代码简洁,相比Grid更易上手
  • ✅ 浏览器兼容性好

3. Flex 布局的两个角色

  • Flex容器:使用display: flex的元素
  • Flex项目:容器的子元素
  • 容器属性用于控制项目如何分布排列,项目属性用于控制自身的大小和位置

4. Flex 与 Grid 的区别

特性FlexGrid
布局维度一维布局二维布局
排列方式按行或列线性排列按行列网格排列
控制方式项目被动适应容器显式定义行列,项目放在网格中
用途导航栏、工具栏、列表、卡片排列复杂网格、仪表盘、页面布局
学习成本低,容易上手高,概念多
主要属性justify-content、align-items、flexgrid-template-rows、grid-template-columns、grid-area
适配对齐主要用于单个方向的对齐分布同时控制行列对齐

选择建议:

  • ✅ 使用Flex:组件内部布局、导航、列表、一维排列
  • ✅ 使用Grid:整体页面布局、复杂多行多列结构
  • 💡 实际应用:通常将Flex和Grid结合使用,Grid做整体布局,Flex做细节排列

二、容器属性

1. display: flex

将元素设置为Flex容器,其子元素自动成为Flex项目。

.container {
  display: flex; /* 块级Flex容器 */
  /* display: inline-flex; */ /* 行内Flex容器 */
}

2. flex-direction - 主轴方向

定义主轴方向,即项目的排列方向。

属性值说明
row默认值,从左到右排列
row-reverse从右到左排列
column从上到下排列
column-reverse从下到上排列
.container {
  display: flex;
  flex-direction: column; /* 纵向排列 */
}

3. flex-wrap - 换行处理

定义项目是否换行,以及换行方向。

属性值说明
nowrap默认值,不换行
wrap换行,新行在下方
wrap-reverse换行,新行在上方
.container {
  display: flex;
  flex-wrap: wrap; /* 项目超出宽度时换行 */
}

4. flex-flow - 简写属性

flex-flowflex-directionflex-wrap的简写。

.container {
  display: flex;
  flex-flow: row wrap; /* 先写direction,再写wrap */
}

5. justify-content - 主轴对齐

控制项目在主轴方向上的对齐方式。

属性值说明
flex-start默认值,左对齐(或上对齐)
flex-end右对齐(或下对齐)
center中心对齐
space-between两端对齐,项目间间距相等
space-around项目两侧间距相等(外边距是内间距一半)
space-evenly项目间间距、边界间距都相等
.container {
  display: flex;
  justify-content: space-between; /* 两端对齐 */
}

6. align-items - 交叉轴对齐(单行)

控制项目在交叉轴方向上的对齐方式(所有项目)。

属性值说明
flex-start默认值,顶部对齐
flex-end底部对齐
center中心对齐
stretch拉伸,填满容器高度
baseline基线对齐
.container {
  display: flex;
  align-items: center; /* 垂直居中 */
  height: 200px;
}

7. align-content - 交叉轴对齐(多行)

当有多行项目时,控制各行在交叉轴上的分布方式。

属性值说明
flex-start默认值,顶部对齐
flex-end底部对齐
center中心对齐
space-between两端对齐,行间间距相等
space-around行两侧间距相等
space-evenly行间间距、边界距离都相等
stretch拉伸,填满容器高度
.container {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between; /* 多行间距相等 */
  height: 400px;
}

8. gap - 项目间距

设置项目之间的间距(CSS最新属性,兼容性好)。

.container {
  display: flex;
  gap: 10px; /* 所有方向间距10px */
  /* gap: 10px 20px; */ /* 行间距10px,列间距20px */
}

容器属性速查表

属性用途常见值
flex-direction主轴方向row、column
flex-wrap换行方式nowrap、wrap
justify-content主轴对齐center、space-between、center
align-items交叉轴对齐(单行)center、stretch
align-content交叉轴对齐(多行)center、space-between
gap项目间距10px、10px 20px

三、项目属性

1. flex - 伸缩综合属性

flexflex-growflex-shrinkflex-basis的简写,是设置项目尺寸的最重要属性。

.item {
  /* flex: flex-grow flex-shrink flex-basis; */
  flex: 1 1 0%; /* 默认值 */
  flex: 1; /* 等同于 flex: 1 1 0% */
}

2. flex-grow - 伸缩比例

定义项目的伸展能力,即如何分配容器的剩余空间。

  • 默认值:0(不伸展)
  • 当容器有剩余空间时,按比例分配给各项目
  • 所有项目的flex-grow之和 > 1时,项目会按比例分配剩余空间
.item1 {
  flex-grow: 1;
}
.item2 {
  flex-grow: 2; /* 比item1多占2倍的剩余空间 */
}

3. flex-shrink - 收缩比例

定义项目的收缩能力,即容器空间不足时如何收缩。

  • 默认值:1(收缩)
  • 当容器空间不足时,按比例收缩各项目
  • 值为0表示不收缩
.item {
  flex-shrink: 1; /* 默认,空间不足时收缩 */
  /* flex-shrink: 0; */ /* 不收缩,保持原始宽度 */
}

4. flex-basis - 基础尺寸

定义项目分配剩余空间之前的基础大小。

  • 默认值:auto(自动计算)
  • 常用值:像素长度、百分比、auto
.item {
  flex-basis: 200px; /* 基础宽度200px */
  /* flex-basis: 50%; */ /* 基础宽度50% */
  /* flex-basis: auto; */ /* 自动计算 */
}

5. align-self - 单个项目对齐

用于覆盖容器的align-items,控制单个项目的交叉轴对齐。

属性值说明
auto默认值,继承容器
flex-start顶部对齐
flex-end底部对齐
center中心对齐
stretch拉伸
baseline基线对齐
.item {
  align-self: flex-end; /* 该项目底部对齐,覆盖容器设置 */
}

6. order - 排序

改变项目在容器中的排列顺序,不影响HTML结构。

  • 默认值:0
  • 值越小越靠前
  • 可以为负数
.item1 {
  order: 3;
}
.item2 {
  order: 1; /* item2会排在item1前面 */
}
.item3 {
  order: 2;
}

项目属性速查表

属性用途常见值
flex伸缩综合属性1、0、1 0 200px
flex-grow伸展比例0、1、2
flex-shrink收缩比例0、1
flex-basis基础尺寸auto、200px、50%
align-self单个项目交叉轴对齐center、flex-end
order排序0、1、-1

四、实用案例

1. 水平居中布局

<div class="container">
  <div class="item">居中内容</div>
</div>
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 200px;
}

2. 导航栏布局

<nav class="navbar">
  <div class="logo">Logo</div>
  <div class="menu">
    <a href="#">首页</a>
    <a href="#">产品</a>
    <a href="#">关于</a>
  </div>
  <div class="user">登录</div>
</nav>
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
  background: #333;
  color: white;
}

.menu {
  display: flex;
  gap: 20px;
}

.menu a {
  color: white;
  text-decoration: none;
}

3. 两栏布局(侧边栏 + 主内容)

<div class="layout">
  <aside class="sidebar">侧边栏</aside>
  <main class="content">主内容</main>
</div>
.layout {
  display: flex;
  height: 100vh;
}

.sidebar {
  flex: 0 0 250px; /* 不伸不缩,宽度250px */
  background: #f0f0f0;
}

.content {
  flex: 1; /* 剩余空间全部分配给主内容 */
  padding: 20px;
}

4. 响应式卡片网格

<div class="grid">
  <div class="card">卡片1</div>
  <div class="card">卡片2</div>
  <div class="card">卡片3</div>
  <div class="card">卡片4</div>
</div>
.grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 calc(33.333% - 14px); /* 3列布局 */
  min-width: 200px; /* 最小宽度 */
  padding: 20px;
  background: white;
  border: 1px solid #ddd;
}

/* 手机端:1列 */
@media (max-width: 768px) {
  .card {
    flex: 1 1 100%;
  }
}

5. 垂直居中弹框

<div class="modal-overlay">
  <div class="modal">弹框内容</div>
</div>
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal {
  background: white;
  width: 400px;
  padding: 30px;
  border-radius: 8px;
}

6. 底部自适应布局

<div class="app">
  <header>头部</header>
  <main>主要内容</main>
  <footer>底部</footer>
</div>
.app {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

header {
  flex: 0 0 60px; /* 高度固定60px */
  background: #333;
}

main {
  flex: 1; /* 占用剩余空间 */
  overflow-y: auto;
}

footer {
  flex: 0 0 40px; /* 高度固定40px */
  background: #f0f0f0;
}

五、Flex 与 Grid 的对比

特性FlexGrid
维度一维二维
用途行或列排列复杂网格布局
学习成本
浏览器兼容性极好很好
推荐场景导航栏、列表、简单布局复杂网格、仪表盘

六、常见问题 & 最佳实践

1. flex:1 的真实含义

.item {
  flex: 1;
  /* 等同于 */
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0%; /* 关键:基础尺寸为0% */
}

设置flex-basis: 0%的好处是:项目的初始宽度为0,项目不会因为内容多少而影响基础宽度,所有剩余空间都会按比例分配。

2. min-width 的坑

.container {
  display: flex;
}

.item {
  flex: 1;
  min-width: 0; /* 重要!避免文本溢出 */
}

Flex项目默认的min-width: auto会导致内容溢出,设置min-width: 0可以让项目正常收缩。

3. 项目宽度处理

/* ✅ 推荐:显式设置flex-basis */
.item {
  flex: 0 0 200px; /* 宽度200px,不伸不缩 */
}

/* ❌ 不推荐:同时设置width和flex-basis */
.item {
  width: 200px;
  flex: 1; /* 冲突 */
}

4. 文本截断

.item {
  flex: 1;
  min-width: 0; /* 必须 */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

5. 不等分布局

<div class="container">
  <div class="left">左边固定宽度</div>
  <div class="right">右边自适应</div>
</div>
.container {
  display: flex;
}

.left {
  flex: 0 0 200px; /* 固定宽度 */
}

.right {
  flex: 1; /* 自适应剩余空间 */
}

七、浏览器兼容性

Flex布局在现代浏览器中兼容性极好:

  • Chrome 29+
  • Firefox 22+
  • Safari 9+
  • IE 11(部分支持,不支持flex-grow在auto宽度下的计算)
  • Edge 全支持

对于需要兼容IE10的项目,可以使用display: -ms-flexbox等前缀。

八、调试技巧

1. 使用浏览器开发者工具

在Chrome/Firefox中,当选中Flex容器时,会自动显示Flex布局的可视化网格,帮助理解项目分布情况。

2. 常用的调试属性

.container {
  border: 1px solid red; /* 显示容器边界 */
  display: flex;
}

.item {
  border: 1px solid blue; /* 显示项目边界 */
  background: rgba(0, 0, 255, 0.1);
}

3. 检查溢出问题

/* 查看是否有内容溢出 */
.item {
  overflow: visible; /* 改成auto或hidden查看 */
}

代码练兵场

预览