Flex 布局完整教程:告别浮动,拥抱万能弹性布局
为什么要抛弃浮动?
在 Flex 出现之前,float: left 是横向排列的唯一指望。但它留下一堆烂摊子:清除浮动的 hack、垂直对齐的崩溃、高度塌陷的幽灵、响应式的补丁堆成山。
Flex 不是"比 float 好一点",而是从模型层面绕开了它的所有缺陷------容器真实感知子项,统一调度空间,一行代码替代十行 hack。
一、30 秒开启 Flex
css
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
css
.container { flex-direction: column; } /* 纵向排列,导航栏/表单常用 */
2. flex-wrap --- 是否换行(必加!)
| 值 | 效果 |
|---|---|
nowrap(默认) |
不换行,空间不足时项目被压缩变形 |
wrap |
自动换行,第一行在上 |
wrap-reverse |
自动换行,第一行在下 |
css
css
.container { flex-wrap: wrap; } /* 90% 的布局错乱,都是因为没加这行 */
3. flex-flow --- 简写
css
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
css
/* 导航栏左右分离,一行搞定 */
.header { justify-content: space-between; }
5. align-items --- 交叉轴对齐(垂直对齐,单行)
| 值 | 效果 |
|---|---|
stretch(默认) |
拉伸填满容器高度 |
flex-start |
顶部对齐 |
flex-end |
底部对齐 |
center |
垂直居中 |
baseline |
按文字基线对齐 |
css
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
css
/* 导航菜单自动填满剩余空间 */
.nav-item { flex: 1; }
/* Logo 不被压缩 */
.logo { flex-shrink: 0; }
五、gap --- 项目间距(2024+ 推荐)
css
css
.container {
display: flex;
gap: 16px; /* 统一间距,不用 margin hack,不用 :last-child */
}
原生支持,简洁优雅,替代所有 margin-right: 0 的防御性代码。
六、完整实战:企业级导航栏
ini
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
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 的本质是让容器真实感知子项、统一调度空间。掌握主轴与交叉轴两根轴线,所有属性一通百通。