我想了解在未设置flex-basis
,width
,min-width
或max-width
属性的显式值的情况下flexbox如何计算最终flex-item的宽度。换句话说,flexbox如何仅根据内容来计算flex-item的宽度?
以下是示例代码(可在codepen上获得):
.container {
display: flex;
width: 600px;
}
.container div {
outline: 1px dotted black;
}
<div class="container">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
<div>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Error ad natus dolores harum, ex fuga voluptates dignissimos possimus saepe officia.</div>
</div>
在此示例中,两个div
(弹性项目)的计算宽度是相同的:300px
(我在“检查元素”调试工具中看到了此宽度)。
现在,如果我在第一个div(forked codepen available here)的文本中再添加10个字符,我会看到第一个div的宽度为311.719px
,而第二个div的宽度为288.281px
。
因此,似乎更多的内容为弹性项目提供了更大的宽度,但是这种基于内容的计算究竟如何工作?如果内容不仅是文本,还包括一些替换的内容(例如图像),那该怎么办?
此外,我通常应该练习显式设置flex-basis
或width
属性,以避免基于内容的元素大小不确定性吗?换句话说,什么是用例不显式设置flex-item的宽度,而将其留给flexbox根据其内容来确定呢?
答案 0 :(得分:4)
对于这种特殊情况,您需要考虑flex-shrink
设置的默认收缩效果,该效果的默认值为1
。最初,您的元素将如下所示溢出:
$('div').each(function() {
console.log($(this).width());
})
.container {
display: flex;
width: 600px;
}
.container div {
outline: 1px dotted black;
flex-shrink:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>
如果您检查元素,则第一个元素为1011.3px
,第二个元素为935.3px
,因此我们的总溢出量为1011.3px + 935.3px - 600px = 1346.6px
。这两个元素的溢出都会减少,因此它们可以放入flex容器中。我们还应该考虑到元素不会以相同的方式收缩,因为它们的初始宽度不同。最大的将收缩更多。然后,我们将得到1011.3/935.3 = 1.08
的因数,公式将为:
x + y = 1346.6 where y = 1.08*x
所以x = 647px
和y = 699.6px
我们将以1011.3px - 699.6px = 311.7px
和935.3px - 673.3px = 288.3px
结尾:
$('div').each(function() {
console.log($(this).width());
})
.container {
display: flex;
width: 600px;
}
.container div {
outline: 1px dotted black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>
flex-shrink属性指定了flex收缩因子,该因子决定了在分配负自由空间时,flex项目相对于flex容器中其余flex项目将收缩多少。 ref
注意:分配负空间时,弯曲收缩系数是乘以弯曲基础尺寸。这会与物品能够收缩的程度成正比地分配负空间,以便例如在大件物品明显减少之前,小件物品不会缩小为零。 ref
完整算法的正式规范:
https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths
请注意,由于默认情况下为an element cannot shrink past its content size,因此存在min-width
约束可能会影响最终计算。
这里与上面的代码相同,其中有一些
,并且您会注意到计算是不同的,因为第一个元素的min-width
约束与第一个句子的长度相等
$('div').each(function() {
console.log($(this).width());
})
.container {
display: flex;
width: 600px;
}
.container div {
outline: 1px dotted black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>
如果通过添加min-width:0
来消除此约束,则会得到以前的值和一些溢出:
$('div').each(function() {
console.log($(this).width());
})
.container {
display: flex;
width: 600px;
}
.container div {
outline: 1px dotted black;
min-width:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>
什么时候内容不仅是文本,还包括替换的内容(例如图像)?
采用相同的逻辑,内容的类型并不重要,重要的是元素的大小和取决于内容的min-width
约束。
此外,我通常应该练习显式设置flex-basis或width属性,以避免基于内容的元素大小不确定吗?
我会说是的。您应该完全控制布局,不要让内容由您自己决定。