小探 flex 渲染机制

由 漆黑菌 于 2021年06月01日 发布

起因

在新dao-table组件中使用了flex布局,对td设置类似flex: 1 1 0的属性可以让子元素等分空间。直到后面给thtd添加了不同的padding,然后thtd就对不齐了。

flex-basis 与 width

flex-basis在flex中类似普通布局中的width,在flex中设置width是不会直接生效的。看上去给flex元素设置width会影响元素尺寸,很多时候是因为flex-basis的默认值是auto。小部分情况下会涉及到跨浏览器表现不一致之类的问题,就暂时无法理解了。含义为根据flex-direction参考width或者height

最初, “flex-basis:auto” 的含义是 “参照我的width和height属性”. 在此之后, “flex-basis:auto” 的含义变成了自动尺寸, 而 “main-size” 变成了 “参照我的width和height属性”。实际执行于 bug 1032922. 然后呢, 这个更改又在 bug 1093316 中被撤销了, 所以 “auto” 变回了原来的含义; 而一个新的关键字 ‘content’ 变成了自动尺寸。 (bug 1105111 包括了增加这个关键字).

牛逼的padding

设置一个div为box-sizing: border-box;width: 100px;padding: 100px;时,div的宽度为left:100px + context:0 + right:100px = 200px。用max-width也不行。在flex中也有这种情况,flex-item的尺寸不会小于左右padding + 左右border + context。

width: auto 和 width: 100%

flex-basisauto时,计算会根据元素width或者height。 很多情况下,一个块级元素宽度为auto或者100%表现似乎是差不多的,然而在flex中,就会暴露了。当width: auto时,flex-basis的计算属性为内容尺寸,也就是说和context有关。

结论

  1. border-box情况下padding顶开 width 的优先级是非常高的,目前还没有发现阻止的方法max-width也不行
  2. padding不是离谱的大的情况下,可以通过在子元素里再套元素来规避问题

意外收获

现在的dao-table其实是一个table+flex的缝合体,于是遇到了好玩的情况。tr一方面是个flex容器,另一方面又要遵守table的计算方式。于是tr的宽度是参考里面的th/td计算(初步推测显式指定用显示指定的,不显式指定根据context自动计算),然后flex再根据flex-basis计算。新旧两代弹性布局逻辑似乎有些相通之处,只不过flex用flex-basis,table用width。