为何我反对使用 flex: 1 简写
众所周知 flex: 1 其实是 flex: 1 1 0 的简写,而我为什么会反对这样写呢,
当然是因为 flex-basic: 0 的表现咯,在浏览器支持的理解上是不同的。
另外文本宽度在 flex-grow 和 overflow: hiiden 的搭配下也有些许不同。
本文将细究一下浏览器在宽度计算时的规律和策略,以此来理解为何 flex-basic: 0 是有问题的。
width: auto
在张鑫旭大佬的《CSS世界》书中有提到,display 盒子其实可以看做是多个盒子共同作用的结果,
比如 inline-block 可认为是 inline 包了个 block 合成的,list-item 是 marker box 和 block 结合才有了圆点;
更甚至,block 下的伪元素可能也是 block > (before-inline block after-inline) 这样的插在其中的嵌套结构。
注意,这里不是 display: inline 或 inline element 意思,而是 inline box 的概念。
大多文章都把 dom tree 和 cssom tree 合成 render tree 这里一笔带过,
我看 w3c 官方文档也不多,以下论述 仅个人总结和理解,还请大佬们勘误。
block box 的初始宽度实为父级宽度,然后才读取的 width 等属性再给出新的实际宽度,
inline box 的初始宽度实为本元素宽度,然后判断父级剩余空间,若超出则以父级宽度为准。
听上去就很容易死循环不是吗,比如子级宽度变了,父级可能会变,父级变了祖父级可能也得变。
我大胆猜测一下,其实只要有个稳定的父级宽度,即可避免掉上面这种死循环的,
比如当本元素宽度变化时,向父级寻找到 block element 即可,该父级之下的所有元素直接重新计算和渲染。
min/max-width
如果说有什么能比 width: 10px !important 权限更高的话,那 max-width 就会说“没错,正是在下”了。
BFC
当 float 时,元素宽度的处理,及其对父级宽度的影响稍有不同。
至于 BFC 中的 position inline-block overflow 等属性的情况,也有所不同,但篇幅有限就不展开了。
flex-shrink
代码语言:html复制<!-- 后续演练皆以此结构为例 -->
<style>
.list { display: flex; width: 500px; }
.list > div { height:50px; }
.item-1 { background: pink; }
.item-2 { background: lightblue; }
.item-3 { background: gray; }
</style>
<div class="list">
<div class="item-1"></div>
<div class="item-2"></div>
<div class="item-3"></div>
</div>flex-shrink 默认为 1,表示弹性子元素在空间不足时等比压缩。
这意味着,假若总宽为 300px 且子元素各有 5, 10, 15 个字且宽度总和超出父级宽度,
那么子元素的宽度将会被分到 50px, 100px, 150px 的收缩后宽度,保持着等比。
而当
flex-grow
flex-grow 默认为 0,表示弹性子元素不参与分配剩余空间。
flex-basic
猜猜看,下面三个子元素的宽度分别会是多少?
代码语言:html复制.item-1 { flex: 1 1 0%; }
.item-2 { flex: 1 1 auto; }
.item-3 { flex: 1 1 200px; }
案例1结果共计 500px,各占了 100px, 100px, 300px,
尚未分配时,子元素宽度为 0 0 200px,空间有余,再按 1, 1, 1 的 flex-grow 分配。
显然,flex-basic 会更与分配前的宽度计算更相关,比如 max-width 那些。
引用
flexbox-essentials


