接触过一阵子 CSS 的人,迟早会被一个问题拦住:怎么把一个元素稳稳地放到页面正中间?我最早学前端的时候,水平居中用 margin: 0 auto,垂直居中要么算行高,要么用绝对定位加 transform,稍不注意整块布局就崩掉。后来 Flex 弹性布局出现,一行 display: flex 配上两个对齐属性,随手一写就是自适应居中。这一讲把 Flex 从头到尾捋一遍,零基础也能跟着试,看完之后你不但能应付日常布局,还能顺手解决不少前端面试题里爱考的 flex 细节。
1. 为什么我劝你直接啃 Flex:一套模型吃掉九成布局需求
1.1 传统布局的“居中困难症”到底难在哪
在 Flex 出现之前,前端的居中就是一门玄学。
- 块级元素水平居中:需要一个固定宽度,然后
margin: 0 auto。没有宽度?失效。 - 文本水平居中:
text-align: center,只对行内内容有效,块级元素内部依旧我行我素。 - 垂直居中:单行文本可以用
line-height模拟,多行文本就要用table-cell的vertical-align魔改。 - 最简单粗暴的是
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%)。这个方案确实好用,但绝对定位会脱离文档流,用它去排一整个页面,后面维护起来就是灾难。
这些方法不是不能用,而是“一个场景一个方案”,没有统一的心智模型。Flex 把问题抽象成了两个角色:容器和项目。所有对齐、伸缩、换行都围绕这两个角色展开,思考方式一下就统一了。
1.2 Flex 的适用边界:能做什么,别拿来做什么
先给没基础的同学划一条线:Flex 是一维布局模型。它擅长解决“一排元素怎么排”“一个元素怎么在区域内对齐”这类问题,典型场景包括导航栏、按钮组、卡片列表、表单元件、弹窗居中等。我这些年做项目,日常布局里八成以上都能用 Flex 解决。
那 Grid 呢?Grid 是二维布局,适合做“既有行又有列”的整体页面骨架,比如整个控制台的仪表盘、商品列表的栅格。Flex 和 Grid 不是二选一的关系,而是互补关系。新手我建议先啃 Flex,因为它的推理链短,属性数量少,能快速建立空间感;Grid 可以在 Flex 熟练之后再上手。
还有一个纪律性问题:别把一个页面所有区域都套上 Flex。遇到复杂页面就层层嵌套 flex,会导致父容器和子容器之间的伸缩规则互相干扰,调试成本极高。判断标准很简单:这段内容是不是只沿着一条轴排?如果不是,考虑 Grid 或者重新拆分模块。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先搞清楚“父容器”和“子项目”:两组属性别混着记
2.1 主轴与交叉轴:所有对齐规则都从这里推导
Flex 有两个轴:主轴和交叉轴。默认情况下,主轴方向是水平向右,交叉轴方向是垂直向下。所有属性名的记忆都建立在“轴”的概念上。
css复制.container {
display: flex;
flex-direction: row; /* 默认值,主轴向右 */
}
属性 flex-direction 决定主轴方向:
row:主轴向右,项目从左往右排列。row-reverse:主轴向左,项目从右往左排列,视觉顺序会反转。column:主轴向下,项目从上往下排列。column-reverse:主轴向上,项目从下往上排列,视觉顺序反转。
排布方向一变,justify-content(主轴对齐)和 align-items(交叉轴对齐)的作用也跟着变。比如导航栏是水平排,主轴对齐就是横向对齐;侧边栏如果是纵向排,主轴对齐就变成纵向对齐。
我自己记法很简单:先写 flex-direction,把主轴在脑子里画出来,再谈对齐。
2.2 容器上的六个核心属性逐个说
这几个属性都写在父容器上,直接作用于所有直接子元素。
display
css复制.container {
display: flex;
}
把当前元素变成块级 Flex 容器,直接子元素变成 flex item。还有一个 display: inline-flex,效果是容器本身变成行内块级表现,适合做按钮内的小型布局,但日常用得少。
flex-direction
控制主轴方向,刚才已经说了。重点说一下 row-reverse 和 column-reverse,很多人在这里翻车:它不只是“换个方向”,它会把项目的起始位置反转。比如原本从左到右排列的 1、2、3,row-reverse 之后是 3、2、1,起始边变成了右侧。
flex-wrap
默认值是 nowrap,意思是不换行。很多新手困惑“为什么我设置了宽度 200px,两个项目却挤到只有 150px”,就是因为父容器宽度不够,而 nowrap 下项目默认会收缩。想把项目排不下时自动换行,就设 flex-wrap: wrap。这个属性和 flex-shrink 经常互相影响,后面第 5 节详细讲。
justify-content
控制主轴方向的对齐方式:
flex-start:向主轴起始边对齐。flex-end:向主轴结束边对齐。center:主轴居中。space-between:首尾贴边,中间平均分配空间。space-around:每个项目两侧有相等的空间,注意首尾的间距是中间的一半。- `space-ev
