在CSS布局方案里,Flex 布局已经成为处理一维排列的首选工具。它把容器内的子项沿主轴和交叉轴进行分配,既能快速完成水平垂直居中,也能在响应式卡片中灵活控制伸缩比例。要真正用好 Flex,关键是分清容器属性和项目属性的边界,以及主轴方向变化时各属性如何响应。下面从基本概念入手,把常用属性和实际代码逐一拆开。

一、Flex布局的核心概念:容器与项目
启用 Flex 布局只需要在父元素上声明 display: flex,这个父元素就变成了 Flex 容器,它的直接子元素会自动成为 Flex 项目。容器负责定义排列方向和换行规则,项目则按照规则分配空间。这里要特别注意,只有直接子元素会参与 Flex 布局,孙元素不会受到影响,除非在孙元素的父级上再次设置 display: flex。
Flex 布局最核心的一对概念是主轴和交叉轴。默认情况下,主轴是水平方向,从左到右;交叉轴是垂直方向,从上到下。主轴的起点和终点分别称为 main start 和 main end,交叉轴的起点和终点分别称为 cross start 和 cross end。项目默认沿着主轴依次排列,容器属性里的 justify-content 控制主轴方向上的对齐,align-items 控制交叉轴方向上的对齐。理解这一点后,很多属性组合就不会再混淆。
下面先给出一个最小示例,三个块级子项原本会垂直堆叠,加上 display: flex 后变成水平排列。
<div class="container"> <div class="item">A</div> <div class="item">B</div> <div class="item">C</div> </div>
.container {
display: flex;
}
.item {
width: 100px;
height: 60px;
background: #4a90d9;
color: #fff;
}
上面的代码中,定义好容器后,三个项目会自动横排。如果不想改变项目原有尺寸,可以暂时不给 flex 相关属性。接下来分别展开容器属性。
二、容器属性详解:排列、换行与对齐
flex-direction 用来改变主轴方向,可选值包括 row、row-reverse、column、column-reverse。默认值是 row,也就是横向从左到右。设置为 column 后,主轴变为垂直方向,项目从上到下排列,此时 justify-content 控制的就是垂直方向的对齐,而 align-items 控制水平方向。这是初学者最容易出错的地方,因为很多人习惯性以为 justify-content 永远管左右、align-items 永远管上下,其实它们对应的是主轴和交叉轴,而不是绝对方向。
当容器宽度不够时,项目默认不会换行,而是挤压每个项目的宽度。通过设置 flex-wrap: wrap 可以让项目在主轴方向排满后换到下一行。与之配合的 align-content 只在多行情况下生效,它控制多行整体在交叉轴上的分布方式。单行时 align-content 不会有任何效果。常见的组合是横向多行布局时使用 flex-direction: row; flex-wrap: wrap; align-content: center;,既能让项目换行,又能把整组内容在垂直方向居中。
对齐属性方面,justify-content 可选 flex-start、flex-end、center、space-between、space-around、space-evenly。其中 space-between 把首尾项目贴边,中间的间距平均分配;space-evenly 则让所有间隔完全相等,包括首尾与边缘之间。下面代码实现项目在主轴上均匀分布,并在交叉轴上居中。
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
align-content: center;
row-gap: 20px;
column-gap: 16px;
}
从代码中可以看到,gap 拆分为 row-gap 和 column-gap 后,可以分别控制行间距和列间距。现代浏览器对 Flex 布局中的 gap 支持已经很好,不需要再通过 margin 来模拟间距,代码更简洁。
三、项目属性详解:伸缩与排序
Flex 项目有三个关键属性:flex-grow、flex-shrink、flex-basis。默认值是 0 1 auto,即不增长、会收缩、基础尺寸为 auto。当容器有剩余空间时,flex-grow 决定项目按什么比例瓜分剩余空间;当容器空间不足时,flex-shrink 决定项目按什么比例收缩。如果把 flex-shrink 设为 0,项目就不会被压缩,哪怕内容溢出容器。
实际开发中更推荐使用简写属性 flex。例如 flex: 1 表示 flex-grow: 1; flex-shrink: 1; flex-basis: 0;,这会让所有项目等分容器空间。与 flex: auto 相比,差异主要在 flex-basis 上:flex: auto 会先根据内容或宽度计算基础尺寸,再分配剩余空间;flex: 1 则忽略内容本身的宽度差异,严格按照比例分。这个区别在制作等宽卡片或导航栏时非常重要。
此外,项目还可以用 align-self 单独覆盖容器设置的 align-items,用 order 调整视觉顺序。需要注意的是 order 只改变渲染顺序,不改变 DOM 结构,也不改变键盘导航和屏幕阅读器的读取顺序,因此在有交互的列表中使用时要谨慎。下面示例让第二个项目单独底部对齐,并让第一个项目排到末尾。
.container {
display: flex;
align-items: flex-start;
}
.item:nth-child(1) {
order: 3;
}
.item:nth-child(2) {
align-self: flex-end;
}
这些属性单独看都不复杂,但合并使用时容易出现预期之外的行为,例如 order 会影响 flex-grow 的视觉顺序吗?不会,它只是移动显示位置,空间分配仍然按照 DOM 原始顺序计算,这一点很多开发者没有意识到。
四、常见实战场景与避坑指南
水平垂直居中是 Flex 最常用的场景之一。传统布局往往需要绝对定位配合负边距或 transform,而 Flex 只要在容器上写两行代码即可实现,前提是容器自身有确定的高度。如果容器高度由内容撑开,垂直居中自然没有可分配空间。下面代码可以快速完成一个登录卡片在页面中的居中。
.page {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.card {
width: 360px;
padding: 32px;
background: #fff;
}
响应式卡片布局也非常适合用 Flex 处理。通过 flex-wrap: wrap 结合每个卡片的 flex-basis,可以避免媒体查询频繁断点。例如希望每行显示三张卡片、间距相等,可以给卡片设置 flex: 1 1 280px;,这样容器宽度变化时会自动调整每行数量。如果希望最后一行不满时卡片也保持相同宽度,就不要用 flex: 1,而是设置固定 flex-basis 并让 flex-grow 为 0,否则最后一张会被拉伸。
一个常见的坑是把 align-items 当成多行对齐属性。当容器设置了 flex-wrap: wrap 且出现换行时,align-items 只对每一行内部的项目生效,而多行整体的对齐需要 align-content。如果只写 align-items: center,多行之间会紧贴在一起,不会整体居中。此时再加上 align-content: center 才能看到效果。另一个坑是给项目设置 margin: auto 会与 justify-content 和 align-items 产生竞争,Margin 在 Flex 项目里会吸收剩余空间,优先级更高,布局结果可能和预期不同,需要根据场景二选一。
总之,Flex 布局的难点不在于属性记忆,而在于理解容器与项目的分工,以及主轴方向变化后各对齐属性对应的物理方向。把基础打牢后,再去看 Grid 布局会更容易建立二维布局的对比体系,两者结合能覆盖绝大多数页面排版需求。
CSS Flex布局弹性盒子flex属性修改时间:2026-09-22 16:08:54