Flex 语法和计算规则
flex 是以下三个 CSS 属性的简写
- flex-grow 设置
flex
元素的增长系数;负值无效,省略时默认值为 1 (初始值为 0) - flex-shrink 设置
flex
元素的收缩系数(仅在默认width/height
之和大于容器时生效);负值无效,省略时默认值为 1 (初始值为 1) - flex-basis 设置
flex
元素在主轴方向上的初始大小;省略时默认值为 0 (初始值为 auto)
语法
单值语法
css
/* 全局属性值 */
/* 初始值 */
flex: initial; => flex: 0 1 auto
/* 从其父级继承 (flex 属性不可被继承,将设置为初始值) */
flex: inherit; => flex: 0 1 auto
/* 是关键字 initial 和 inherit 的组合(当属性可继承时为 inherit 不可继承时为 initial) */
flex: unset; => flex: 0 1 auto
/* 关键字值 */
/* 根据自身的宽度与高度来确定尺寸 弹性 */
flex: auto; => flex: 1 1 auto
/* 根据自身宽高来设置尺寸 非弹性 */
flex: none; => flex: 0 0 auto
/* 无单位数: flex-grow */
flex: 2; => 2 1 0
/* 一个有效的 width/height 值: flex-basis */
flex: 10px; => 1 1 10px
flex: 20em; => 1 1 20em
flex: min-content; => 1 1 min-content
双值语法
- 第一个值必须为一个无单位数
- 第二个值必须为以下之一
- 无单位数: 当作
flex-shrink
值 - 有效的
width/height
值: 当作flex-basis
值
- 无单位数: 当作
css
/* 无单位数: flex-grow | flex-shrink */
flex: 2 2; => 2 2 0
/* 有效的 width/height 值: flex-grow | flex-basis */
flex: 2 30px; => 2 1 30px
三值语法
- 第一个值必须为一个无单位数,当作
flex-grow
值 - 第二个值必须为一个无单位数,当作
flex-shrink
值 - 第三个值必须为一个有效的
width/height
值,当作flex-basis
值
css
flex: 2 2 10%;
小测试
以下小测试均计算 width
flex 元素宽度之和小于容器
flex-grow 总和大于 1
html
<style>
* {
margin: 0;
padding: 0;
}
.box {
display: flex;
margin: 50px;
width: 1000px;
height: 300px;
}
.left {
flex: 1 3 200px;
background: #95b8d1;
}
.center {
flex: 2 2 300px;
background: #dda789;
}
.right {
flex: 3 1 400px;
background: #c3d899;
}
</style>
<div class="box">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
解答
分析代码可以得出,我们需要计算 flex
元素的增长系数 flex-grow
- 计算
flex
元素宽度总和:200 + 300 + 400 = 900px
- 计算剩余容器宽度:
1000 - 900 = 100px
- 计算
flex-grow
系数总和:1 + 2 + 3 = 6
- 计算
flex
元素实际宽度(width
+ 剩余空间)- left:
200 + 100 / 6 * 1 = 216.67px
- center:
300 + 100 / 6 * 2 = 333.33px
- right:
400 + 100 / 6 * 3 = 450px
- left:
flex-grow 总和小于 1
html
<style>
* {
margin: 0;
padding: 0;
}
.box {
display: flex;
margin: 50px;
width: 1000px;
height: 300px;
background: #666;
}
.left {
flex: 0.1 3 200px;
background: #95b8d1;
}
.center {
flex: 0.2 2 300px;
background: #dda789;
}
.right {
flex: 0.3 1 400px;
background: #c3d899;
}
</style>
<div class="box">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
解答
分析代码可以得出,我们需要计算 flex
元素的增长系数 flex-grow
- 计算
flex
元素宽度总和:200 + 300 + 400 = 900px
- 计算剩余容器宽度:
1000 - 900 = 100px
- 计算
flex-grow
系数总和:0.1 + 0.2 + 0.3 = 0.6
- 计算
flex
元素实际宽度(width
+ 剩余空间)- left:
200 + 100 / 1 * 0.1 = 210px
- center:
300 + 100 / 1 * 0.2 = 320px
- right:
400 + 100 / 1 * 0.3 = 430px
- left:
- 最后剩余的
40px
不分配
注意点
- 当
flex-grow
系数之和大于 1 时: 各个元素按比例占满剩余空间 - 当
flex-grow
系数之和小于 1 时: 剩余空间不会全部分配给各个元素
flex-grow 计算公式
sh
# 当 flex-grow 总和小于 1 时按 1 处理
元素宽度 + 剩余空间 / flex-grow 系数总和 * flex-grow 系数 = 实际宽度
flex 元素宽度之和大于容器
html
<style>
* {
margin: 0;
padding: 0;
}
.box {
display: flex;
margin: 50px;
width: 1000px;
height: 300px;
}
.left {
flex: 1 3 300px;
background: #95b8d1;
}
.center {
flex: 2 2 400px;
background: #dda789;
}
.right {
flex: 3 1 500px;
background: #c3d899;
}
</style>
<div class="box">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
解答
分析代码可以得出,我们需要计算 flex
元素的收缩系数 flex-shrink
- 计算
flex
元素宽度总和:300 + 400 + 500 = 1200px
- 计算溢出的宽度:
1200 - 1000 = 200px
- 计算总权重:
3 * 300 + 2 * 400 + 1 * 500 = 2200
- 计算 flex 元素实际宽度(
width
- 溢出宽度)- left:
300 - 200 * 3 * 300 / 2200 = 218.19px
- center:
400 - 200 * 2 * 400 / 2200 = 327.28px
- right:
500 - 200 * 1 * 500 / 2200 = 454.55px
- left:
flex-shrink 计算公式
sh
# 总权重计算: 各元素的宽度乘以其 flex-shrink 的总和
元素宽度 - 溢出宽度 * flex-shrink 系数 * 元素宽度 / 总权重 = 实际宽度