flex 是 Flex 布局中核心的复合属性 ,用于控制弹性项目(flex item)在弹性容器(flex container)中的伸缩规则 ,它是 flex-grow、flex-shrink、flex-basis 三个子属性的简写,语法为:
css
flex: [flex-grow] [flex-shrink] [flex-basis];
默认值:flex: 0 1 auto(即 flex-grow:0、flex-shrink:1、flex-basis:auto)。
一、先理解三个子属性的独立作用
1. flex-grow:扩展因子(放大比例)
- 作用 :当弹性容器有剩余空间时,项目是否/如何瓜分剩余空间。
- 取值 :非负数字(无单位),默认
0。 - 规则 :
flex-grow: 0:不参与剩余空间分配(默认行为);flex-grow: n(n>0):项目按比例瓜分剩余空间,总份数为所有项目flex-grow之和,单个项目占比 = 自身flex-grow/ 总份数。
- 示例 :
容器宽度 500px,包含 3 个项目,宽度分别为 100px、100px、100px,剩余空间 = 500 - 300 = 200px。- 项目1:
flex-grow: 1,项目2:flex-grow: 2,项目3:flex-grow: 1→ 总份数 4; - 项目1 分配:200 * (1/4) = 50px → 最终宽度 150px;
- 项目2 分配:200 * (2/4) = 100px → 最终宽度 200px;
- 项目3 分配:200 * (1/4) = 50px → 最终宽度 150px。
- 项目1:
2. flex-shrink:收缩因子(缩小比例)
- 作用 :当弹性容器空间不足(项目总宽度 > 容器宽度)时,项目是否/如何被压缩。
- 取值 :非负数字(无单位),默认
1。 - 规则 :
flex-shrink: 0:不压缩,项目保持flex-basis宽度(可能溢出容器);flex-shrink: n(n>0):项目按「flex-shrink * flex-basis」的比例被压缩(核心:不是直接按flex-shrink比例,而是结合基准宽度)。
- 示例 :
容器宽度 300px,包含 2 个项目:- 项目1:
flex-basis: 200px; flex-shrink: 1; - 项目2:
flex-basis: 200px; flex-shrink: 2; - 总溢出:400 - 300 = 100px;
- 压缩权重总和:(2001) + (2002) = 600;
- 项目1 压缩:100 * (200*1)/600 ≈ 33.33px → 最终宽度 166.67px;
- 项目2 压缩:100 * (200*2)/600 ≈ 66.67px → 最终宽度 133.33px。
- 项目1:
3. flex-basis:基准宽度
- 作用 :定义项目在「伸缩前」的初始宽度(优先级高于
width/height,前提是 flex 主轴为水平/垂直)。 - 取值 :
auto:默认,取项目自身的宽度(若未设置width,则为内容宽度);- 具体数值(如
100px、20%):固定基准宽度; 0:基准宽度为 0,此时flex-grow分配的是「纯剩余空间」(而非「剩余空间+项目宽度」)。
- 关键区别 :
flex-basis: autovsflex-basis: 0
容器宽度 500px,2 个项目都设flex-grow: 1:- 项目1/2 无宽度,
flex-basis: auto→ 基准宽度为内容宽度(假设各 50px),剩余空间 500-100=400px,各分 200px → 最终宽度 250px; - 项目1/2
flex-basis: 0→ 基准宽度 0,剩余空间 500px,各分 250px → 最终宽度 250px(看似结果相同,但逻辑不同);
若项目有固定宽度(如width: 100px): flex-basis: auto→ 基准宽度=100px,剩余空间 500-200=300px,各分 150px → 最终 250px;flex-basis: 0→ 基准宽度=0,剩余空间 500px,各分 250px → 最终 250px(结果仍相同,但flex-basis:0更「纯粹」按比例分配)。
- 项目1/2 无宽度,
二、flex 简写的常见取值及含义
1. 单值语法
| 取值 | 等价于 | 含义 |
|---|---|---|
flex: n |
flex: n 1 0% |
n 为正数,flex-grow:n,flex-shrink:1,flex-basis:0%(常用); |
flex: auto |
flex: 1 1 auto |
可伸缩、可收缩,基准宽度为自身宽度(等价于默认值改 flex-grow:1); |
flex: none |
flex: 0 0 auto |
不可伸缩、不可收缩,基准宽度为自身宽度(固定宽度,不响应容器); |
flex: 100px |
flex: 1 1 100px |
基准宽度 100px,可伸缩、可收缩; |
2. 双值语法
| 取值 | 等价于 | 含义 |
|---|---|---|
flex: a b |
flex: a b 0% |
flex-grow:a,flex-shrink:b,flex-basis:0%; |
flex: a 100px |
flex: a 1 100px |
flex-grow:a,flex-shrink:1,flex-basis:100px; |
3. 三值语法
flex: grow shrink basis → 完全对应三个子属性(如 flex: 2 3 200px)。
4. 最常用的简写场景
flex: 1:等价1 1 0%,项目均分剩余空间(最常用的「等分布局」);
示例:容器内 3 个项目都设flex:1→ 各占 1/3 宽度;flex: auto:等价1 1 auto,项目先按自身宽度排列,剩余空间均分,不足时压缩;flex: none:等价0 0 auto,项目固定宽度(不伸缩、不收缩),溢出容器则显示滚动/溢出;flex: 0 auto:等价默认值0 1 auto,项目不放大,不足时收缩,基准宽度为自身宽度;flex: 2:等价2 1 0%,项目占比是flex:1项目的 2 倍(如 2:1 分栏)。
三、关键注意事项
1. flex-basis 优先级高于 width/height
- 若主轴为水平(
flex-direction: row),flex-basis覆盖width; - 若主轴为垂直(
flex-direction: column),flex-basis覆盖height; - 例外:
flex-basis: auto时,width/height生效(作为基准宽度)。
2. flex-shrink: 0 防止项目被压缩
- 场景:按钮/固定宽度元素,避免容器变窄时被挤压(如
flex: 0 0 120px); - 若设
flex-shrink: 0但flex-basis过大,项目会溢出容器(需配合overflow处理)。
3. 避免混用 flex 和 width/height
- 若已设置
flex: 1(等价flex-basis:0%),再设width无意义(flex-basis优先级更高); - 若需固定宽度,优先用
flex: 0 0 100px而非width:100px(更符合 flex 逻辑)。
4. 浏览器兼容性
- 现代浏览器(Chrome/Firefox/Safari 9+/Edge)完全支持;
- 旧版 IE(IE10-)需加前缀(
-ms-flex),且部分属性行为不一致(建议放弃兼容)。
四、实战示例
示例1:等分三栏布局
css
.container {
display: flex;
width: 100%;
height: 200px;
}
.item {
flex: 1; /* 等价 1 1 0%,均分宽度 */
border: 1px solid #000;
}
示例2:固定侧边栏 + 自适应主内容
css
.container {
display: flex;
width: 100%;
}
.sidebar {
flex: 0 0 200px; /* 固定200px,不伸缩、不收缩 */
background: #eee;
}
.main {
flex: 1; /* 自适应剩余空间 */
background: #fff;
}
示例3:容器不足时,部分项目不压缩
css
.container {
display: flex;
width: 300px; /* 总宽度不足 */
}
.item1 {
flex: 0 0 150px; /* 固定150px,不压缩 */
background: #f00;
}
.item2 {
flex: 1; /* 可压缩,占剩余空间 */
background: #0f0;
}
总结
flex 属性的核心是「先确定基准宽度(flex-basis),再根据容器空间是否充足,通过 flex-grow 放大或 flex-shrink 缩小」:
- 等分布局:
flex: 1; - 固定宽度:
flex: 0 0 固定值; - 自适应+可收缩:
flex: auto; - 固定不可变:
flex: none。
掌握这三个子属性的交互逻辑,就能精准控制 flex 项目的布局行为。