Flex 布局完整教程:告别浮动,拥抱万能弹性布局

16 阅读4分钟

Flex 布局完整教程:告别浮动,拥抱万能弹性布局


为什么要抛弃浮动?

在 Flex 出现之前,float: left 是横向排列的唯一指望。但它留下一堆烂摊子:清除浮动的 hack、垂直对齐的崩溃、高度塌陷的幽灵、响应式的补丁堆成山

Flex 不是"比 float 好一点",而是从模型层面绕开了它的所有缺陷——容器真实感知子项,统一调度空间,一行代码替代十行 hack。


一、30 秒开启 Flex

css
.container {
  display: flex;  /* 就这一行,子元素自动变成弹性项目 */
}

开启后,子元素的 floatclearvertical-align 全部失效。不是 bug,是特性。


二、先搞懂两个核心概念

概念说明
Flex 容器设置了 display: flex 的父元素,制定排列规则
Flex 项目容器内的直接子元素,遵循规则排列
主轴(Main Axis)项目排列的方向,默认水平从左到右
交叉轴(Cross Axis)永远垂直于主轴

记住一句话:父管整体排列,子管单独样式。  样式加错位置,布局直接归零。


三、容器属性:控制整体布局(80% 场景只用这些)

1. flex-direction — 主轴方向

效果
row(默认)水平从左到右
row-reverse水平从右到左
column垂直从上到下
column-reverse垂直从下到上
css
.container { flex-direction: column; }  /* 纵向排列,导航栏/表单常用 */

2. flex-wrap — 是否换行(必加!)

效果
nowrap(默认)不换行,空间不足时项目被压缩变形
wrap自动换行,第一行在上
wrap-reverse自动换行,第一行在下
css
.container { flex-wrap: wrap; }  /* 90% 的布局错乱,都是因为没加这行 */

3. flex-flow — 简写

css
flex-flow: row wrap;  /* 等价于 flex-direction: row + flex-wrap: wrap */

4. justify-content — 主轴对齐(水平对齐)

效果高频场景
flex-start靠左对齐(默认)导航左对齐
flex-end靠右对齐
center居中登录框居中
space-between两端贴边,中间间距相等左右分离布局
space-around每个项目两侧间距相等图片画廊
space-evenly所有间距完全相等均匀分布
css
/* 导航栏左右分离,一行搞定 */
.header { justify-content: space-between; }

5. align-items — 交叉轴对齐(垂直对齐,单行)

效果
stretch(默认)拉伸填满容器高度
flex-start顶部对齐
flex-end底部对齐
center垂直居中
baseline按文字基线对齐
css
.container { align-items: center; }  /* 垂直居中,告别 line-height hack */

6. align-content — 多行交叉轴对齐

⚠️ 只有 flex-wrap: wrap 生效后才有用,单行时不起作用。

取值与 justify-content 一致:flex-start / flex-end / center / space-between / space-around / stretch


四、项目属性:控制单个元素

属性作用常用值
order排列顺序,数值越小越靠前-1, 0, 1
flex-grow放大比例,默认为 0(不放大)0, 1, 2
flex-shrink缩小比例,默认为 1(等比缩小)0, 1, 2
flex-basis初始主轴尺寸,默认为 auto200px25%
align-self单独覆盖 align-items同 align-items 各值
flex以上三个的简写none / auto / 1 / 0 0 200px

flex 简写速查

写法等价于场景
flex: 11 1 0%等分剩余空间(最常用)
flex: auto1 1 auto自适应
flex: none0 0 auto固定大小
flex: 0 0 200px不放大不缩小,固定 200px固定列宽
css
/* 导航菜单自动填满剩余空间 */
.nav-item { flex: 1; }

/* Logo 不被压缩 */
.logo { flex-shrink: 0; }

五、gap — 项目间距(2024+ 推荐)

css
.container {
  display: flex;
  gap: 16px;  /* 统一间距,不用 margin hack,不用 :last-child */
}

原生支持,简洁优雅,替代所有 margin-right: 0 的防御性代码。


六、完整实战:企业级导航栏

html
<header class="header">
  <div class="logo">Flex后台管理系统</div>
  <nav class="nav-list">
    <a href="#" class="active">首页</a>
    <a href="#">数据统计</a>
    <a href="#">用户管理</a>
    <button class="login-btn">立即登录</button>
  </nav>
</header>
css
.header {
  display: flex;
  justify-content: space-between;  /* 左右分离 */
  align-items: center;             /* 垂直居中 */
  height: 60px;
  padding: 0 40px;
}

.nav-list {
  display: flex;
  align-items: center;
  gap: 35px;  /* 统一间距 */
}

效果:Logo 左、菜单右、全部垂直居中、间距均匀、响应式友好。  浮动方案需要 15 行 hack,Flex 只要 8 行。


七、Flex vs 浮动:对比总结

维度浮动 floatFlex
垂直对齐近乎失控align-items: center 一行搞定
清除浮动必须 clearfix不存在这个问题
响应式补丁堆砌flex-direction: column 一句切换
顺序调整改 HTML 结构order 属性搞定
等高列min-height hack天然等高
间距控制margin 计算gap 原生支持

八、避坑清单

  1. display: flex 加在父元素上,加在子元素上完全无效
  2. 子元素超过一行必须加 flex-wrap: wrap,否则会被压缩变形
  3. flex: 1 是等分剩余空间,不是固定宽度
  4. 开启 Flex 后子元素的 float / clear / vertical-align 失效,需显式重置 float: none
  5. IE10/11 对 flex: 1 支持不完美,写成 flex: 0 0 100% 更稳

一句话总结:Flex 的本质是让容器真实感知子项、统一调度空间。掌握主轴与交叉轴两根轴线,所有属性一通百通。