案例
下面这段代码估计大家经常会用到,目的是让.main自适应。
.ctn {
display: flex;
width: 500px;
height: 200px;
}
.main {
flex: 1;
background-color: red;
}
.left {
width: 100px;
background-color: yellow;
}
.right {
width: 200px;
background-color: green;
}
<div class="ctn">
<div class="left"></div>
<div class="main"></div>
<div class="right"></div>
</div>
大家都知道设置
flex: 1可以让元素自适应宽度,但却不知道其原理,比如我们把.ctn的宽度设为200px,再看看效果,我们会发现.main消失了
规则
flex其实是flex-grow flex-shrink flex-basis的缩写,默认是0 1 auto 其它还有flex: 0 flex: none flex: auto可参考表格
| flex | flex-grow | flex-shrink | flex-basis |
|---|---|---|---|
| default | 0 | 1 | auto |
| 1 | 1 | 1 | 0% |
| 0 | 0 | 1 | 0% |
| none | 0 | 0 | auto |
| auto | 1 | 1 | auto |
记起来也很简单
flex: num === flex: num 1 0%flex: none伸缩是0flex: auto伸缩是1
分析
让我们回到案例,我们给.main设置了flex: 1,相当于flex: 1 1 0% 伸缩都是1,总有点矛盾,到底是伸还是缩?这要取决于flex盒子的剩余宽度
在flex盒子宽度过剩时,会使用子元素的flex-grow计算,在flex盒子的宽度不足时,会使用子元素的flex-shrink计算
1.当.ctn宽度为500px时,
- 盒子剩余宽度为
500 - 500 * 0% - 100- 200 = 200 .left和.right没有设置相当于flex: 0 1 auto,所以总放大比例为1 + 0 + 0 = 1.left总宽度100 + 200 * (0 / 1) = 100.right总宽度200 + 200 * (0 / 1) = 200.main总宽度500 * 0% + 200 * (1 / 1) = 200- 总结计算公式:
基础宽度 + 盒子剩余宽度 * (放大比例 / 总放大比例)
- 当
.ctn宽度为200px时,
- 盒子不足宽度为
500 * 0% + 100 + 200 - 200 = 100 .left和.right没有设置相当于flex: 0 1 auto,所以总缩放权重为500 * 0% * 1 + 100 * 1 + 200 * 1 = 300.left总宽度100 - 100 * (100 * 1 / 300) = 66.66.right总宽度200 - 100 * (200 * 1 / 300) = 133.33.main总宽度500 * 0% - 100 * (0 * 1 / 300) = 0- 总结计算公式:
基础宽度 - 盒子不足宽度 * (缩放权重 / 总缩放权重)
虽然仅仅只有flex: 1一行代码,但其实是包含了复杂的计算的
最后我们在看一个例子
<div class="ctn">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
<div class="item4"></div>
<div class="item5"></div>
<div class="item6"></div>
</div>
.ctn {
margin: 100px;
display: flex;
width: 500px;
height: 500px;
}
.item1 {
width: 100px;
flex: 1;
background-color: red;
}
.item2 {
width: 100px;
flex: 0;
background-color: green;
}
.item3 {
width: 100px;
flex: none;
background-color: yellow;
}
.item4 {
width: 100px;
flex: auto;
background-color: pink;
}
.item5 {
width: 200px;
flex: 1 1 100px;
background-color: gray;
}
.item6 {
width: 200px;
flex: 2 1 20%;
background-color: blue;
}
- 先结合
flex-basis和width计算总宽度500 * 0% + 500 * 0% + 100 + 100 + 100 + 500 * 20% = 400 - 剩余宽度
500 - 400 = 100,使用放大计算方式 - 总放大比例
1 + 0 + 0 + 1 + 1 + 2 = 5 item1宽度500 * 0% + 100 * (1 / 5) = 20item2宽度500 * 0% + 100 * (0 / 5) = 0item3宽度100 + 100 * (0 / 5) = 100item4宽度100 + 100 * (1 / 5) = 120item5宽度100 + 100 * (1 / 5) = 120item6宽度500 * 50% + 100 * (2 / 5) = 140
需要注意flex-basis和width的取值方式:
flex-basis为百分比时,按父元素宽度 * 百分比flex-basis为具体px时,按具体pxflex-basis为auto或者没设置时,按width来