flex布局子元素大小的计算问题1:flex-auto到底是怎么计算的?
不知道下面的思考是否正确,是否还有欠考虑的地方?还有一些我觉的有矛盾的地方
案例一 子元素显式设置了宽度
<body>
<div class="A">
<div class="B"></div>
</div>
</body>
.A {
display: flex;
}
.B {
width: 500px;
height: 200px;
background: red;
}
.B
元素的flex
属性的默认值为0 1 auto
,即flex-basis: 0; flex-grow: 0; flex-shrink: 1;
B的flex-basis: auto;的计算值为500px。
A的宽度就是最大占满父元素的宽度,当A的宽度大于500时,B的宽度小于A的宽度,不需要收缩,增长设置为0,故B保持不变。
当A的宽度小于500时,B的宽度就收缩和A的宽度相同。
但是当我们给.B
添加一个很长的元素时,
<body>
<div class="A">
<div class="B">
<div class="C"></div>
</div>
</div>
</body>
.A {
display: flex;
}
.B {
width: 500px;
height: 200px;
background: red;
}
.C {
width: 900px;
height: 200px;
background:yellow;
}
但是,此时无论怎么改变A的宽度,B的大小都为500px这为什么呢?当A的宽度大于500时它应该保持为500px,不应该增加,因为我们设置flex-grow: 0;。当A的宽度小于500的时候,此时A应该收缩,但是它的min-content的宽度为900px(或者说min-width为900px),所以不能收缩了。
案例二 子元素宽度没有显式设置
1
如果上面的B元素不设置宽度那么auto的计算值就是B的子元素的大小,即900px。那么,此时B元素的宽度会保持为900px无论A的宽度大于900px还是小于900px。原因分析和上面的一样。
2
<body>
<div class="A">
<div class="B">lorem100</div>
<div class="B">lorem100</div>
</div>
</body>
B
的flex-basis: auto,其实就是它的max-content的值(即不换行的长度),如果两个B
的宽度大于A的宽度,收缩B的宽度=A的宽度/2。
案例三 子元素不显式设置宽度并设置overflow-x: auto
.A {
display: flex;
}
.B {
overflow-x: auto;
background: red;
}
.C {
width: 900px;
height: 200px;
background:yellow;
}
flex-basis: auto; 计算得到B的宽度为C的宽度为900px,但是B是滚动容器,此时它的min-content就是不900px了,它可以很小。所以当A的宽度大于900时,B保持900不变,当A小于900时和就收缩到和A的宽度一样。
再添加一个元素D
<body>
<div class="A">
<div class="B">
<div class="C">
<div class="D"></div>
</div>
</div>
</div>
</body>
.A {
display: flex;
}
.B {
overflow-x: auto;
}
.C {
}
.D {
width: 900px;
height: 100px;
background:red;
}
B的宽度取决于C的宽度取决于D的宽度,即B的flex-basis:auto;计算得到是900px。分析同上,A的宽度大于900px,B保持900px,A的宽度小于900px,B收缩到和A的宽度一样。
C的宽度呢?
C其实是不属于flex布局的,它属于flow布局,并且它是一个block,宽度最大充满其父元素的宽度,即它的宽度始终和B的相同。
但是这句话是不是和上面加粗的矛盾啊?上面说B的宽度取决于C的宽度取决于D的宽度,下面说C的宽度最大充满B的宽度。
这里有一个codesandbox的在线环境可以自己试一下。