<div class="container">
<div class="item">abdfdofewefdfdsdfewfwefdf</div>
<div class="item"><img src="https://demo.cssworld.cn/new/images/nature-8.jpg"></div>
<div class="item">务开发时遇到的,为了便于清晰描述,我这里写了一个能复现上述问d题的简化</div>
</div>
.container {
display: flex;
flex-wrap: wrap;
width: 420px;
border: 1px green solid;
}
.item {
flex: 1;
border: 1px blue dotted;
}
img[src*="nature"] {
width: 100px;
}
问题: flex:1 等价于 flex: 1 1 0%, 既然flex-basis是0%,那么flex子元素 应该优先使用最小内容宽度吧,第一个子元素的最小内容宽度就是 文本 abdfdofewefdfdsdfewfwefdf
的宽度,
第二个flex子元素的最小内容宽度就是图片本身的宽度100px,
第三个flex子元素的最小内容宽度 应该是单个中文字符的宽度吧?
所以剩余空间=flex容器宽度-三个flex子元素的最小内容宽度
然后把这个剩余空间等比例分配给每一个子元素, 所以我理解中的 渲染效果应该是类似下图:
每一个绿色框框都是一个flex子元素
红色框框部分是 该flex子元素 分配到的 剩余空间。
然而实际渲染的结果 看起来好像剩余空间 都给了第三个flex子元素,请问我的理解错在了哪里?
如果 flex-basis 明确设置了,那么剩余空间的大小就是容器的大小减去每一个元素的 flex-basis 大小。如果 flex-basis 没有明确设置,那么会从元素的 width, max-width, max-content 等属性中确定元素的 flex-basis 大小。
这里的每一个元素的 flex-basis 都为 0%,因此剩余空间的大小就是容器的宽度大小减去元素的边框大小。由于每一个元素的的 flex-grow 都是 1,那么每一个元素分配的大小就是 (420 - 3 x 2) / 3 = 138。由于第一个元素其首选最小宽度大于 138,当分配的大小小于该大小时取首选最小宽度,因此第一个元素会占据大约 218.48(可能会因为浏览器的默认使用字体不同有所变化,包括了边框大小)。这会导致剩余空间的大小重新计算,因此剩余两个元素的分配大小变为 (420 - 218.48 - 2 x 2) / 2 = 98.76。同样的原因会导致第二个元素取其首选最小宽度,也就是 100,如果包括边框,那么第二个元素的大小就占据 102。这样最后一个元素分配的大小变为 420 - 218.48 - 102 - 1 x 2 = 97.52,如果加上边框就是 99.52。
简单来说就是最小内容宽度不是用来确定剩余空间的,而是用来约束最终元素的大小的。如果希望让计算更加直观,最好把子元素的边框删除,这样计算起来简单一点。