flex布局在开发中的作用:
1.解决以前需要用定位position,浮动float,百分比%来解决的布局问题,
2.解决以前比较难以把握的垂直居中问题vertical-align
面试中很容易碰到一个题:
左边200px,右边占满整屏
以前的写法,会用到左边写固定200px,后边的元素margin-left:200px,然后加上浮动float,有了flex之后呢,写法非常方便
.left
width 200px
.right
flex 1
自动占满剩余的空间,是不是特别6,当然这个是题外话,我们要学的是flex:grow,flex:shrink
flex: grow
MDN是这样描述的:
CSS属性 flex-grow
设置了一个flex项主尺寸的flex增长系数。它指定了flex容器中剩余空间的多少应该分配给项目(flex增长系数)。
怎么样,看懂了吗,我自己看了也晕,还是来些栗子吧
section
div.left
div.center
div.right
section
display flex
width 600px
height 100px
.left
flex-grow 1
width 100px
background red
.center
flex-grow 2
width 200px
background yellow
.right
flex-grow 3
width 16px
background green
上面这个栗子在实际运行中,会是怎样呢
是不是有点意思呢,宽度都按特定的比例拉伸了,这就是我们flex:grow的功效了
- 在子元素的flex-grow加起来大于1的时候,要算出实际宽度。
- 首先计算出子元素相对父元素的剩余宽度,在这里是600-100-200-16=284
- 计算第一个方块的实际宽度:284*1(flex-grow)/6(子元素flow-grow总和)+100(样式定义的width)=147.33,第二个跟第三个不妨自己试着算算
flex-grow还有一种情况是,flow-grow总和小于1的情况,这时候算法跟上面有所不同:
栗子:还是拿上面栗子来看,把flow-grow的值全部改为0.n,相对应
.left
flex-grow 0.1
width 100px
background red
.center
flex-grow 0.2
width 200px
background yellow
.right
flex-grow 0.3
width 16px
background green
试着想一想会得到什么样的一个布局呢,
看图,我已经放在下面了
当子元素的flow-grow加起来不足1的时候,这时候,父元素就会有空间不被占满,那么这个时候得子元素实际宽度是多少呢:
- 在子元素的flex-grow加起来小于1的时候,要算出实际宽度。
- 首先计算出子元素相对父元素的剩余宽度,在这里是600-100-200-16=284
- 计算第一个方块的实际宽度:284*0.1(flex-grow)/1(子元素flow-grow总和)+100(样式定义的width)=128.4,第二个跟第三个不妨自己试着算算
当然啦,这个flex-grow的值是被min/max-width的影响的,自己实际运用的时候要注意哦
flex:shrink
CSS flex-shrink
属性指定了 flex 元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。
同样附上MDN关于flex:shrink的描述。。哈哈
flex:grow是拉伸填补空位,那么flex:shrink则是相对立的,它会收缩哦,也就是子元素的宽度要大于父元素的宽度
同样我们也来上一个栗子:
还是沿用上面的代码,但是我们得修改下css
.left
flex-shrink 1
width 200px
background red
.center
flex-shrink 2
width 300px
background yellow
.right
flex-shrink 3
width 160px
background green
相信聪明的你已经发现了吧,没错,200+300+160=660,这个值已经超出了父容器的600宽度了,这个时候,在实际运行中会是怎样的呢:
依旧来张图吧~
怎么样,都按照一定的比例自己收缩了吧,是不是很神奇~
flex:shrink跟flex:grow的算法还是有一定差异的,这里有几个数值要注意(溢出值,总宽度):
- 先计算出子元素的溢出值 200+300+160-600=60。
- 然后计算子元素的总宽度,2001+3002+160*3=1280
- 计算第一个方块的实际宽度:200 - 601(flex-shrink)200(width)/1280=190.62,第二个跟第三个不妨自己试着算算
这个算法是不是有点不好理解呢,其实总宽度就是把flex:shrink当作是份额,子元素是每一份,每一份*份额再相加,这样就算出了总宽度;然后再算出溢出值在每个子元素中占的份额,再用子元素的实际宽度减去溢出份额就得到实际宽度啦~
当然了,flex:shrink也有小于1的情况,思考下,如果shrink大于1的情况,经过缩小刚好跟总宽度相等;那么如果小于1的时候会出现什么情况呢
来了来了他来了,
小于1的情况,子元素得不到充分的缩比,依旧会伸到容器外部
194.38 + 283.12 + 146.5 = 624,怎么样,虽然这个时候子元素依然有缩小,但是依旧大于父容器的600,神奇吧
那么,这个时候是怎么计算的实际宽度呢:
- 先计算出子元素的溢出值 200+300+160-600=60
- 而这个时候得溢出值已经不能拿来直接计算了,因为子元素的flex-shrink的总和没有1,只有0.6,此时的溢出值要用60*0.6=36来计算了
- 然后计算子元素的总宽度,2000.1+3000.2+160*0.3=128
- 计算第一个方块的实际宽度:200 - 360.1(flex-shrink)200(width)/128=194.38,第二个跟第三个不妨自己试着算算
当然啦,flex-shrink也会受到max/min-width的影响哦
原文转载:https://segmentfault.com/a/1190000023037468