Flex 布局完整教程:告别浮动,拥抱万能弹性布局
为什么要抛弃浮动?
在 Flex 出现之前,float: left 是横向排列的唯一指望。但它留下一堆烂摊子:清除浮动的 hack、垂直对齐的崩溃、高度塌陷的幽灵、响应式的补丁堆成山。
Flex 不是"比 float 好一点",而是从模型层面绕开了它的所有缺陷——容器真实感知子项,统一调度空间,一行代码替代十行 hack。
一、30 秒开启 Flex
css
.container {
display: flex; /* 就这一行,子元素自动变成弹性项目 */
}
开启后,子元素的
float、clear、vertical-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 | 初始主轴尺寸,默认为 auto | 200px, 25% |
align-self | 单独覆盖 align-items | 同 align-items 各值 |
flex | 以上三个的简写 | none / auto / 1 / 0 0 200px |
flex 简写速查
| 写法 | 等价于 | 场景 |
|---|---|---|
flex: 1 | 1 1 0% | 等分剩余空间(最常用) |
flex: auto | 1 1 auto | 自适应 |
flex: none | 0 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 浮动:对比总结
| 维度 | 浮动 float | Flex |
|---|---|---|
| 垂直对齐 | 近乎失控 | align-items: center 一行搞定 |
| 清除浮动 | 必须 clearfix | 不存在这个问题 |
| 响应式 | 补丁堆砌 | flex-direction: column 一句切换 |
| 顺序调整 | 改 HTML 结构 | order 属性搞定 |
| 等高列 | min-height hack | 天然等高 |
| 间距控制 | margin 计算 | gap 原生支持 |
八、避坑清单
display: flex加在父元素上,加在子元素上完全无效- 子元素超过一行必须加
flex-wrap: wrap,否则会被压缩变形 flex: 1是等分剩余空间,不是固定宽度- 开启 Flex 后子元素的
float/clear/vertical-align失效,需显式重置float: none - IE10/11 对
flex: 1支持不完美,写成flex: 0 0 100%更稳
一句话总结:Flex 的本质是让容器真实感知子项、统一调度空间。掌握主轴与交叉轴两根轴线,所有属性一通百通。