基础的 flexbox 布局方法, 大家都比较熟悉了, 日常画页面 flexbox 布局用的 66 的, 灵活布局, 不同移动设备的适配我也不在话下, 可是同事问我:"知道 flex 的具体是怎么计算的吗", 我一脸懵, 我也不清楚呢, 既然不懂就要学♀, 写给未来男朋友呀.
疑问:
一, 如何收缩尺寸来避免父元素溢出?
二, 怎样增加尺寸来填满未使用的空间?
今天就写篇 flex 的收缩算法给同事, 也给未来男朋友呀. 如果你想看 flex 基础的, 可以移步到 flex MDN, 要是来看 flex 收缩算法 你就来对地方了, 里面有一些数学计算, 不过都很简单. 为了计算出有多少可用空间能布局于 flex 子元素, 浏览器必须知道这个 item 有多大才能开始. 接下来我们来看看不同情况下的 item 是怎么计算的.
一, 如何收缩尺寸来避免父元素溢出?
我们举个(项目的压缩因子相加小于 1 时):
一个宽度为 500px 的容器, 里面的是三个项目分别是 150px,200px,250px, 分别对项目 1 和项目 2 设置 flex-shrink 为 2,3, 项目 3 不设置, 默认 flex-shrink 为 1.
image
第一步: 计算项目溢出值
500 - (150 + 200 + 250) = -100px
第二步: 计算各个项目的宽度乘以 flex-shrink 的总权重
150 * 2 + 200 * 3+ 250 * 1 = 1150
第三步: 计算各个项目压缩空间的大小
总溢出空间 * 项目宽度 * flex-shrink / 总权重, 计算的时候值如果为小数, 则向下取整.
item1 的最终宽度为: 150 - 100 * 150 * 2 / 1150 ≈ 123
item2 的最终宽度为: 200 - 100 * 200 * 3 / 1150 ≈ 147
item3 的最终宽度为: 250 - 100 * 250 * 1 / 1150 ≈ 228
最终效果
第二个(项目的压缩因子相加小于 1 时):
一个宽度为 500px 的容器, 里面的是三个项目分别是 150px,200px,250px, 分别对项目 1, 项目 2 和项目 3 设置 flex-shrink 为 0.1,0.2,0.3.
image
第一步: 计算项目溢出值
500 - (150 + 200 + 250) = -100px
溢出空间 = 溢出值 * ( 收缩因子之和 / 1 ):
溢出空间: 100 * (0.1 + 0.2 + 0.3) / 1 = 60
第二步: 计算各个项目的宽度乘以 flex-shrink 的总权重
总权重为 150 * 0.1 + 200 * 0.2 + 250 * 0.3 = 130
第三步: 计算各个项目压缩空间的大小
项目的实际大小 = 项目的指定宽度 - 溢出空间 * 项目宽度 * 收缩因子 / 总权重
item1 的最终宽度为: 150 - 60 * 150 * 0.1 / 130 ≈ 143px
item2 的最终宽度为: 200 - 60 * 200 * 0.2 / 130 ≈ 181px
item3 的最终宽度为: 250 - 60 * 250 * 0.3 / 130 ≈ 215px
最终效果
当项目在主轴方向上溢出时, 通过设置项目收缩因子来压缩项目适应容器就告一段落了. 先喝点茶, 稍作休息, 继续看看当项目在主轴方向上撑不满容器的时候, 是怎么扩张来填满容器的.
二, 怎样增加尺寸来填满未使用的空间 ?
举个(当项目的扩张因子相加大于 1 时):
一个宽度为 500px 的容器, 里面的是三个项目分别是 120px,150px,200px, 分别对项目 1 和项目 2 设置 flex-grow 为 2,1, 项目 3 不设置, 默认 flex-grow 为 0.
image
第一步: 计算容器的剩余空间
500 - (120 + 150 + 200) = 30px
第二步: 分配剩余的空间
30px / ( 2+ 1 + 0) = 10px
第三步: 计算各个项目扩张空间的大小
项目宽度 + (每份扩张配额 / 当前项目的扩张因子)
item1 的最终宽度为: 120 + 10 * 2 = 140
item2 的最终宽度为: 150 + 10 * 1 = 160
item3 的最终宽度为: 200 + 10 *0 = 200
最终效果
最后一个(当项目的扩张因子相加小于 1 时):
一个宽度为 500px 的容器, 里面的是三个项目分别是 120px,150px,200px, 分别对项目 1, 项目 2, 项目 3 设置 flex-grow 为 0.3,0.2,0.1.
image
第一步: 计算容器的剩余空间
500 - (120 + 150 + 200) = 30px
第二步: 分配剩余的空间
Flex-grow 相加 0.3 + 0.2 + 0.1 = 0.6 < 1
剩余空间按 30 / 1 = 30px 划分.
第三步: 计算各个项目扩张空间的大小
项目自由宽度 + 剩余空间 * (每份扩张配额 / 1) ≈ 项目实际宽度
item1 的最终宽度为: 120 + 30 * (0.3 / 1) = 129
item2 的最终宽度为: 150 + 30 * (0.2 / 1) = 156
item3 的最终宽度为: 200 + 30 * (0.1 / 1) = 209
最终效果
感谢 @xoyoz @SYJ 的指正. 所有子项目 flex-grow 之和小于 1 的时, 不会把所有的剩余空间都分配给子元素.
小结
妈耶, 终于计算完了. 咳咳! 总算弄清了 flex 的收缩算法, 写给未来男朋友看的 flex 完结 .如果这篇文档也有帮助到你, 记得点赞, 评论, 关注三连击呀
如上内容均为自己总结, 难免会有错误或者认识偏差, 如有问题, 希望大家留言指正, 以免误人, 若有什么问题请留言, 会尽力回答!
来源: http://www.jianshu.com/p/6f2b95b840f4