CSS Flexbox 完整教学 2026:一次搞懂弹性排版的核心概念
快速解答
Flexbox 是 CSS 的弹性排版系统,只要对父元素加上 `display: flex`,子元素就能自动弹性排列。用 `justify-content` 控制水平分布,`align-items` 控制垂直对齐,几行 CSS 就能搞定大部分排版难题。
为什么 Flexbox 是现代排版的首选?
还记得用 float 排版的年代吗?浮动完还要清除浮动(clearfix),垂直居中要算负 margin,等高栏位甚至要用 JavaScript 计算……那个年代真的不好过。
CSS Flexbox 的出现改变了这一切。
过去的排版痛苦:
- 垂直居中:
position: absolute+transform: translateY(-50%)这种奇怪写法 - 等高栏位:需要 JavaScript 动态计算每个栏位的高度
- 水平均分:
float+ 百分比宽度,小数点误差容易让最后一个元素掉下去 - 调整元素顺序:只能修改 HTML 结构
Flexbox 的解法(只要几行):
/* 水平 + 垂直居中,过去要写 10 行,现在 3 行 */
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}现在连垂直居中这个千年难题都能轻松解决。
目前所有主流浏览器都支持 Flexbox,你可以放心在任何项目中使用。如果你的网站也需要在不同设备上完美呈现,记得搭配RWD响应式设计一起学习。
两个核心角色:Container 与 Item
学 Flexbox 最重要的一件事:它分成两个层级,Container 掌控全局,Item 接受指令并可以有自己的弹性。
Container(容器)— 指挥官
.container {
display: flex; /* 声明:我是 flex 容器! */
}加上 display: flex 的元素就是 Container,负责决定子元素怎么排列、要不要换行、间距怎么分配。
Item(项目)— 士兵
/* Container 的直接子元素,自动成为 Item */
<div class="container">
<div>Item 1</div> ← flex item
<div>Item 2</div> ← flex item
<div>Item 3</div> ← flex item
</div>注意:只有直接子元素才是 flex item,孙元素不受影响。
主轴与交叉轴
Flexbox 的排列由两条轴线决定,这是理解所有属性的关键:
- 主轴(Main Axis):flex item 排列的方向
- 交叉轴(Cross Axis):垂直于主轴的方向
/* 默认:主轴水平(→),交叉轴垂直(↓) */
.container { flex-direction: row; }
/* 改为:主轴垂直(↓),交叉轴水平(→) */
.container { flex-direction: column; }justify-content 永远控制主轴,align-items 永远控制交叉轴,记住这个规则就不会搞混。
Container 六大必学属性
1. flex-direction(主轴方向)
flex-direction: row; /* → 水平排列(默认) */
flex-direction: row-reverse; /* ← 反向水平排列 */
flex-direction: column; /* ↓ 垂直排列 */
flex-direction: column-reverse; /* ↑ 反向垂直排列 */2. justify-content(主轴分布)
控制 item 在主轴上如何分布,是最常用的属性之一:
justify-content: flex-start; /* 靠起点对齐(默认) */
justify-content: flex-end; /* 靠终点对齐 */
justify-content: center; /* 居中 */
justify-content: space-between; /* 两端对齐,中间间距均分 */
justify-content: space-around; /* 每个 item 两侧间距相等 */
justify-content: space-evenly; /* 所有间距完全相等 */点下方按钮看实际效果:
justify-content 互动对比
当前值:flex-start
3. align-items(交叉轴对齐)
控制 item 在交叉轴(垂直方向)的对齐方式:
align-items: stretch; /* 撑满交叉轴(默认) */
align-items: flex-start; /* 靠起点对齐 */
align-items: flex-end; /* 靠终点对齐 */
align-items: center; /* 居中 */
align-items: baseline; /* 文字基线对齐 */4. flex-wrap(换行设置)
flex-wrap: nowrap; /* 不换行,item 超出容器会被压缩(默认) */
flex-wrap: wrap; /* 超出容器宽度就自动换行 */5. gap(间距)
比 margin 更简洁的间距写法,只在 item 之间产生间距:
gap: 1rem; /* row 和 column 间距都是 1rem */
gap: 1rem 2rem; /* row-gap: 1rem, column-gap: 2rem */6. flex-flow(简写)
flex-direction + flex-wrap 的合体:
flex-flow: row wrap; /* 最常用:水平排列 + 允许换行 */
flex-flow: column nowrap; /* 垂直排列 + 不换行 */ Item 属性:让子元素控制自己的弹性
Container 属性管全局,Item 属性让个别子元素自主调整大小与对齐。
flex-grow(弹性放大)
数字代表「抢剩余空间的比例」,0 代表不抢:
.item-a { flex-grow: 1; } /* 抢 1 份 */
.item-b { flex-grow: 2; } /* 抢 2 份(是 a 的两倍) */
.item-c { flex-grow: 0; } /* 不抢,维持原本大小 */flex-shrink(弹性缩小)
容器不够大时,item 缩小的比例,0 代表不缩小:
.item { flex-shrink: 1; } /* 默认,会依比例缩小 */
.item { flex-shrink: 0; } /* 不缩小,就算超出容器也不压缩 */图片、Logo 通常设置 flex-shrink: 0,避免被压扁。
flex-basis(基础大小)
item 在分配剩余空间前的初始大小:
.item { flex-basis: 200px; } /* 初始宽度 200px */
.item { flex-basis: auto; } /* 由内容决定(默认) */
.item { flex-basis: 0; } /* 忽略内容大小,从 0 开始计算 */flex(三者的简写)
最推荐的写法,同时设置 grow / shrink / basis:
.item { flex: 1; } /* = flex: 1 1 0%,均分剩余空间 */
.item { flex: auto; } /* = flex: 1 1 auto */
.item { flex: none; } /* = flex: 0 0 auto,固定大小 */
.item { flex: 0 0 200px; } /* 固定 200px,不放大不缩小 */flex: 1 是做等宽栏位最常用的写法,记起来!
align-self(单个 item 的对齐覆盖)
覆盖 container 的 align-items,只影响自己:
.special {
align-self: flex-end; /* 只有这个 item 靠底部 */
}order(排列顺序)
数字越小越排前面,默认都是 0:
.item { order: -1; } /* 强制排最前面 */
.item { order: 2; } /* 排到后面 */ 实战:三个最常见的排版场景
场景一:垂直 + 水平居中(最常用)
.center-box {
display: flex;
justify-content: center; /* 水平 */
align-items: center; /* 垂直 */
height: 200px;
}Flexbox 居中效果
场景二:导航栏(Logo 左、链接右)
.navbar {
display: flex;
justify-content: space-between; /* Logo 靠左,按钮靠右 */
align-items: center;
padding: 0 1.5rem;
} 场景三:等高卡片排版
不管卡片内容多少,align-items: stretch(默认值)让所有卡片高度自动对齐:
.cards {
display: flex;
gap: 1rem;
}
.card {
flex: 1; /* 均分宽度 */
/* 高度由 stretch 默认值自动等高 */
}等高卡片排版
注意三张卡片高度完全一致,这就是 align-items: stretch 的效果——让所有 item 撑满容器高度。
常见问题解答
Q:flex: 1 和 width: 100% 有什么区别?
A: flex: 1 是「分配剩余空间的比例」,多个 item 设置后会共享空间;width: 100% 是「占父容器全宽」,多个 item 都设置的话会叠在一起(除非搭配 flex-wrap: wrap)。
想要等宽栏位,用 flex: 1;想要某个 item 独占整行,用 flex-basis: 100% 或 width: 100%。
Q:justify-content 没有效果?
A: 确认这三点:
- 父元素是否有
display: flex - 容器宽度是否足够(如果 item 已经占满容器,就没有剩余空间可分配)
- item 是否设置了
flex-grow: 1(会抢光剩余空间,让 justify-content 无效)
Q:Flexbox vs CSS Grid,该用哪个?
A: 两者不冲突,看场景选择:
- Flexbox:一个方向的排列(行 or 列),适合导航栏、按钮组、一排卡片
- CSS Grid:同时控制行 and 列,适合整页版型、复杂的二维排版
实务上通常混搭:用 Grid 做页面整体结构,用 Flexbox 做组件内部排列。
Q:手机版想改成垂直排列怎么做?
A: 搭配 media query 改变 flex-direction:
.container {
display: flex;
gap: 1rem;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
}
} Flexbox 属性速查表
Container 属性
| 属性 | 常用值 | 说明 |
|---|---|---|
display | flex | 启用 Flexbox |
flex-direction | row / column | 主轴方向 |
justify-content | center / space-between / space-evenly | 主轴分布 |
align-items | center / stretch / flex-end | 交叉轴对齐 |
flex-wrap | wrap / nowrap | 是否换行 |
gap | 1rem | item 间距 |
flex-flow | row wrap | direction + wrap 简写 |
Item 属性
| 属性 | 常用值 | 说明 |
|---|---|---|
flex | 1 / none / 0 0 200px | grow + shrink + basis 简写 |
flex-grow | 0 / 1 | 放大比例 |
flex-shrink | 0 / 1 | 缩小比例 |
flex-basis | auto / 200px | 基础大小 |
align-self | center / flex-end | 覆盖单个 item 的对齐方式 |
order | 数字 | 排列顺序,越小越前面 |
最常用的三个组合,背起来:
/* 垂直水平居中 */
display: flex;
justify-content: center;
align-items: center;
/* Navbar:Logo 左,按钮右 */
display: flex;
justify-content: space-between;
align-items: center;
/* 等宽卡片排版 */
display: flex;
gap: 1rem;
.card { flex: 1; }掌握 Flexbox 之后,下一步可以学CSS Grid来处理二维排版,或者深入了解RWD响应式设计,让排版在手机、平板、桌机上都完美显示。