前言
Flex 布局(Flexible Box)已成为现代前端开发的标配。它不仅解决了垂直居中的百年难题,还通过强大的动态伸缩能力适配各种屏幕。本文将带你从容器到项目,深度解析 Flex 的每一个细节。
一、 基本概念
Flex 布局通过设置 display: flex 开启。
- 容器 (Flex Container) :采用 Flex 布局的元素。
- 项目 (Flex Item) :容器内部的所有直接子元素。
二、 容器属性 (Container Properties)
容器属性控制项目的排列方向、换行方式及对齐。
1. 排列与换行
-
flex-direction:决定主轴方向。row(默认):水平,左起。row-reverse:水平,右起(项目顺序也会反转)。column:垂直,上起。
-
flex-wrap:一行放不下时如何处理。nowrap(默认):不换行,项目会强制挤压。wrap:正常换行。
-
flex-flow:简写属性,默认row nowrap。
2. 对齐方式
-
justify-content:主轴(水平)对齐。flex-start(默认):左对齐flex-end:右对齐center:水平居中space-between:两端对齐,项目之间间隔相等space-around:每个项目两侧间隔相等
-
align-items:交叉轴(垂直)对齐(单行)。stretch(默认):项目未设高度则撑满。flex-start:交叉轴的起点对齐。flex-end:交叉轴的终点对齐。center:垂直居中baseline:项目第一行文字基线对齐。
-
align-content:多根轴线(多行)的对齐方式。若项目只有一根轴线(即不换行),该属性无效。(目前还未使用过🤷)
三、 项目属性:Flex 复合属性详解
这是 Flex 的精髓,由 flex-grow, flex-shrink, flex-basis 组成,默认值为 0 1 auto。
1. flex-grow:剩余空间的瓜分者
它是用来分配剩余空间的,就是当子元素元素宽带没有超过父元素宽度时,从而根据flex-grow的值来拉长子元素宽度。
- 默认 0:即便有剩余空间也不放大。
- 逻辑:当容器宽度 > 子元素总宽度时,按权重分配剩余空间。
- 注意:如果所有
flex-grow总和 < 1,剩余空间不会被占满。
2. flex-shrink:溢出空间的承担者
子元素的宽度之和大于容器的时候才会生效,会根据flex-shrink的值控制子元素收缩比例。
- 默认 1:当空间不足时,项目等比例收缩。
- 逻辑:当容器宽度 < 子元素总宽度时生效。设置为
0则表示不收缩。
3. flex-basis:项目的初始主轴尺寸
它是用来设置flex子元素的宽度,它相比于width,它的优先级更高。
-
默认 auto:宽度取自
width属性;若没有设置width,则由内容撑开。 -
优先级:
flex-basis>width。 -
计算细节:
-
它的默认值为auto,当为auto的时候width属性是有效的,如果没有设置width那么宽度就是内容自适应
-
当
flex-basis的值为0%时,设置了width值- 如果内容自适应宽度小于width值的话,width值将无效,宽度将为内容自适应
- 如果内容自适应宽度大于width值的话,width值将有效,宽度为width值
-
当
flex-basis的值为0%时,没有设置width值- 宽度将为内容自适应
-
当
flex-basis设置了值,没有设置width值- 如果内容自适应宽度小于
flex-basis值的话,宽度将为flex-baise值 - 如果内容自适应宽度大于
flex-basis值的话,宽度为自适应宽度
- 如果内容自适应宽度小于
-
当
flex-basis设置了值,也设置了width值-
flex-basis的值大于width,元素宽度均为flex-baise值- 如果内容自适应宽度小于
flex-basis值的话,宽度将为flex-baise值 - 如果内容自适应宽度大于
flex-basis值的话,宽度也为flex-baise值
- 如果内容自适应宽度小于
-
flex-basis的值小于width:
-
如果内容自适应宽度小于
flex-basis值的话,宽度将为flex-baise值 -
如果内容自适应宽度大于flex-basis值的话
- 宽度小于width的值,宽度为之自适应宽度
- 宽度大于width的值,宽度为width值
-
-
-
四、 常用 Flex 简写及其表现
在实际开发中,我们常用这几个简写:
| 简写方式 | 等价于 | 表现 |
|---|---|---|
flex: 1 | 1 1 0% | 等分空间。项目会拉伸占满剩余空间,且由于 basis 为 0%,所有项目公平竞争。 |
flex: auto | 1 1 auto | 自适应拉伸。在项目原始尺寸基础上拉伸,适合双栏布局。 |
flex: 0 | 0 1 0% | 不拉伸,但可收缩,最终尺寸趋于内容自适应。 |
flex: none | 0 0 auto | 无论空间多大或多小,项目都保持原始尺寸,既不拉伸也不收缩。 |
五、 实战:三栏布局实现
利用 flex: 1 可以轻松实现左右固定、中间自适应的布局:
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="left"></div>
<div class="main"><div class="content"></div></div>
<div class="right"></div>
</div>
<script></script>
</body>
<style>
html,
body {
height: 100vh;
margin: 0;
padding: 0;
}
.container {
width: 100%;
height: 100%;
overflow: auto;
display: flex;
}
.left,
.right {
flex: 0 0 200px;
background: greenyellow;
height: 100vh; /* 关键:与容器同高 */
position: sticky; /* 可选:滚动时粘在顶部 */
top: 0;
}
.main {
flex: 1;
}
.content {
width: 100%;
height: 10000px;
}
</style>
</html>