1. flex: 0 (等价于 flex: 0 1 0%)
css
.item {
flex-grow: 0; /* 不扩展 */
flex-shrink: 1; /* 可以收缩 */
flex-basis: 0%; /* 基础尺寸为 0 */
}
2. flex: 1 (等价于 flex: 1 1 0%)
css
.item {
flex-grow: 1; /* 扩展填满剩余空间 */
flex-shrink: 1; /* 可以收缩 */
flex-basis: 0%; /* 基础尺寸为 0,完全由 grow 决定 */
}
3. flex: none (等价于 flex: 0 0 auto)
css
.item {
flex-grow: 0; /* 不扩展 */
flex-shrink: 0; /* 不收缩 */
flex-basis: auto; /* 基于内容的固有尺寸 */
}
4. flex: auto (等价于 flex: 1 1 auto)
css
.item {
flex-grow: 1; /* 扩展填满剩余空间 */
flex-shrink: 1; /* 可以收缩 */
flex-basis: auto; /* 基于内容的固有尺寸 */
}
选择指南
| 属性 | 何时使用 | 典型场景 |
|---|---|---|
| flex: 0 | 元素有固定尺寸,不占额外空间 | 按钮、图标、固定宽度组件 |
| flex: 1 | 需要占满剩余空间 | 主内容区、等分布局 |
| flex: none | 保持原始尺寸,不被压缩 | Logo、重要按钮、图片 |
| flex: auto | 内容驱动的弹性布局 | 标签页、表单控件、响应式组件 |
记忆技巧:
- flex: 0 - "我不要额外空间"
- flex: 1 - "给我所有剩余空间"
- flex: none - "保持我的原样"
- flex: auto - "我很灵活,看情况调整"
flex: 0 vs flex: none 的核心区别
关键差异:flex-shrink(收缩能力)
css
/* flex: 0 */
flex-grow: 0; /* 不扩展 ✓ 相同 */
flex-shrink: 1; /* 可以收缩 ⚠️ 关键区别 */
flex-basis: 0%; /* 基础尺寸为 0 */
/* flex: none */
flex-grow: 0; /* 不扩展 ✓ 相同 */
flex-shrink: 0; /* 不能收缩 ⚠️ 关键区别 */
flex-basis: auto; /* 基于内容尺寸 */
记忆技巧
决策流程图
less
需要固定尺寸的元素?
↓ 是
容器空间不足时,这个元素可以被压缩吗?
↓ 可以 ↓ 不可以
flex: 0 flex: none
(适应性固定) (刚性固定)
简单记忆法
- flex: 0 = "我是固定的,但可以妥协"(可收缩)
- flex: none = "我是固定的,绝不妥协"(不收缩)
实际应用
当你不确定用哪个时,问自己:
- 如果容器空间不够,这个元素可以被压缩吗?
- 这个元素的尺寸是否绝对不能改变?
如果答案是"可以压缩" → 用 flex: 0
如果答案是"绝不能变" → 用 flex: none
flex: 1 vs flex: auto 的核心区别
关键差异:flex-basis(初始尺寸计算)
css
/* flex: 1 */
flex-grow: 1; /* 扩展 ✓ 相同 */
flex-shrink: 1; /* 收缩 ✓ 相同 */
flex-basis: 0%; /* 忽略内容尺寸 ⚠️ 关键区别 */
/* flex: auto */
flex-grow: 1; /* 扩展 ✓ 相同 */
flex-shrink: 1; /* 收缩 ✓ 相同 */
flex-basis: auto; /* 基于内容尺寸 ⚠️ 关键区别 */
实际效果对比
场景1:不同长度的内容
less
// 容器宽度:600px
<Flex style={{width: '600px', border: '1px solid red'}}>
<div style={{flex: 1, background: 'lightblue', textAlign: 'center'}}>
短
</div>
<div style={{flex: 1, background: 'lightgreen', textAlign: 'center'}}>
这是一段比较长的文本内容
</div>
<div style={{flex: 1, background: 'lightyellow', textAlign: 'center'}}>
中等长度
</div>
</Flex>
flex: 1 的结果:
- 每个元素都是 200px 宽(600px ÷ 3)
- 完全忽略内容长度,强制等分
less
<Flex style={{width: '600px', border: '1px solid red'}}>
<div style={{flex: 'auto', background: 'lightblue', textAlign: 'center'}}>
短
</div>
<div style={{flex: 'auto', background: 'lightgreen', textAlign: 'center'}}>
这是一段比较长的文本内容
</div>
<div style={{flex: 'auto', background: 'lightyellow', textAlign: 'center'}}>
中等长度
</div>
</Flex>
flex: auto 的结果:
- 长文本元素:约 280px(基础尺寸更大)
- 短文本元素:约 120px(基础尺寸更小)
- 中等文本元素:约 200px
- 先考虑内容尺寸,再分配剩余空间
场景2:混合内容类型
css
<Flex style={{width: '500px'}} gap={16}>
{/* 按钮 */}
<Button style={{flex: 1}}>确定</Button>
<Button style={{flex: 1}}>取消</Button>
<Button style={{flex: 1}}>重置数据</Button>
</Flex>
flex: 1 的效果:
- 三个按钮完全等宽
- "重置数据"按钮内的文字可能显得很松散
css
<Flex style={{width: '500px'}} gap={16}>
{/* 按钮 */}
<Button style={{flex: 'auto'}}>确定</Button>
<Button style={{flex: 'auto'}}>取消</Button>
<Button style={{flex: 'auto'}}>重置数据</Button>
</Flex>
flex: auto 的效果:
- "重置数据"按钮会稍微宽一些(因为文字更长)
- 每个按钮的宽度更符合内容需求
记忆技巧
核心原则:需要视觉统一用 flex: 1,需要内容自然用 flex: auto!
决策流程
less
需要元素填满剩余空间?
↓ 是
希望所有元素完全等分吗?
↓ 是 ↓ 否
flex: 1 flex: auto
(强制等分) (内容驱动)
简单记忆法
- flex: 1 = "我要平均分配,不管内容多少"(忽略内容)
- flex: auto = "我要分配空间,但要考虑我的内容"(考虑内容)
视觉比喻
想象分蛋糕:
- flex: 1:不管谁的胃口大小,每人分到完全相同的一块
- flex: auto:先看每人的基本需求,然后把剩余的平分
在实际开发中,90% 的"占满剩余空间"需求都用 flex: 1的原因
-
避免了内容的干扰
-
在不同屏幕尺寸下表现一致
-
flex: 1计算更高效:- 跳过内容尺寸计算步骤
- 减少重排(reflow)的可能性
- 在复杂布局中性能更好
css
/* flex: 1 的计算 */
flex-basis: 0%; /* 跳过内容尺寸计算 */
/* 直接计算:剩余空间 ÷ flex-grow 总和 */
/* flex: auto 的计算 */
flex-basis: auto; /* 需要先计算内容尺寸 */
/* 然后计算:(剩余空间 - 内容尺寸) ÷ flex-grow 总和 + 内容尺寸 */