如果没有设置 flex-basis 或宽度,flexbox 如何计算 flex-item 的宽度? [英] How flexbox calculates flex-item's width if no flex-basis or width are set?

查看:18
本文介绍了如果没有设置 flex-basis 或宽度,flexbox 如何计算 flex-item 的宽度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解当没有为 flex-basiswidthmin-widthmax-width 属性被设置.换句话说,flexbox 是如何仅根据内容来计算 flex-item 的宽度的?

这是一个示例代码(可在 codepen 上获得):

.container {显示:弹性;宽度:600px;}.container div {轮廓:1px 黑色虚线;}

<div>Lorem ipsum dolor sat amet consectetur adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div><div>Lorem ipsum dolor sat, amet consectetur adipisicing elit.Error ad natus dolores harum, ex fuga voluptates dignissimos possimus saepe offcia.</div>

在此示例中,两个 div(弹性项目)的计算宽度相同:300px(我使用检查元素"调试工具看到).

现在,如果我在第一个 div 的文本中再添加 10 个字符(此处提供分叉的代码笔),我看到第一个 div 的宽度为 311.719px 而第二个 div 的宽度为 288.281px.

因此似乎更多的内容为 flex-item 提供了更多的宽度,但是这种基于内容的计算究竟是如何工作的?当内容不仅是文本而且还有一些替换的内容(例如图像)时呢?

此外,我通常应该练习明确设置 flex-basiswidth 属性以避免基于内容的元素大小的不确定性吗?换句话说,什么是不明确设置 flex-item 的宽度并让 flexbox 根据其内容来确定它的用例?

解决方案

对于这种特殊情况,您需要考虑 flex-shrink 设置的默认收缩效果,其默认值为 1.最初你的元素会像下面这样溢出:

$('div').each(function() {console.log($(this).width());})

.container {显示:弹性;宽度:600px;}.container div {轮廓:1px 黑色虚线;弹性收缩:0;}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div class="容器"><div>Lorem ipsum dolor sat amet consectetur adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!123456789

<div>Lorem ipsum dolor sat amet consectetur adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>

如果您检查元素,第一个元素将为 1011.3px,第二个元素为 935.3px,因此我们总共有 1011.3px 溢出+ 935.3px - 600px = 1346.6px.这两个元素的溢出都会减少,因此它们可以放入 flex 容器中.我们还应该考虑到元素不会以相同的方式收缩,因为它们没有相同的初始宽度.最大的会缩小更多.然后我们将有一个因子 1011.3/935.3 = 1.08,公式为:

x + y = 1346.6 其中 y = 1.08*x

所以 x = 647pxy = 699.6px

我们将以 1011.3px - 699.6px = 311.7px935.3px - 673.3px = 288.3px 结束:

$('div').each(function() {console.log($(this).width());})

.container {显示:弹性;宽度:600px;}.container div {轮廓:1px 黑色虚线;}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div class="容器"><div>Lorem ipsum dolor sat amet consectetur adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!123456789

<div>Lorem ipsum dolor sat amet consectetur adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>


<块引用>

flex-shrink 属性指定了 flex 收缩因子,它决定了当分配负的可用空间时,flex 项相对于 flex 容器中的其余 flex 项 收缩的程度.ref

注意:分配负空间时,弹性收缩系数乘以弹性基础尺寸.这会根据项目能够缩小的程度来分​​配负空间,例如在较大的项目明显减少之前,小项目不会缩小为零.ref

完整算法的官方规范:

https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths


请注意,min-width 约束可能会影响最终计算,因为默认情况下 an元素不能缩小超过其内容大小.

这是与上面相同的代码,带有一些 &nbsp;,您会注意到计算不同,因为第一个元素具有 min-width 约束等于我们有 &nbsp;

的第一句话的长度

$('div').each(function() {console.log($(this).width());})

.container {显示:弹性;宽度:600px;}.container div {轮廓:1px 黑色虚线;}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div class="容器"><div>Lorem&nbsp;ipsum&nbsp;dolor&nbsp;sit&nbsp;amet&nbsp;consectetur&nbsp;adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!123456789

<div>Lorem ipsum dolor sat amet consectetur adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>

如果您通过添加 min-width:0 删除此约束,您将获得以前的值和一些溢出:

$('div').each(function() {console.log($(this).width());})

.container {显示:弹性;宽度:600px;}.container div {轮廓:1px 黑色虚线;最小宽度:0;}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div class="容器"><div>Lorem&nbsp;ipsum&nbsp;dolor&nbsp;sit&nbsp;amet&nbsp;consectetur&nbsp;adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!123456789

<div>Lorem ipsum dolor sat amet consectetur adipisicing elit.Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>


<块引用>

当内容不仅是文本而且还有一些替换的内容(例如图像)时呢?

应用相同的逻辑,内容的类型并不重要,重要的是元素的大小和依赖于内容的 min-width 约束.

<块引用>

另外,我通常应该练习明确设置 flex-basis 或 width 属性以避免基于内容的元素大小的不确定性吗?

我会说是的.您应该完全控制您的布局,不要让内容为您做决定.

I want to understand how flexbox calculates final flex-item's width when no explicit value is set for flex-basis, width, min-width or max-width properties are set. In other words, how flexbox calculates flex-item's width based solely on content?

Here is an example code (available on 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>

In this example computed width of both divs (flex-items) is the same: 300px (which I see with "inspect element" debug tools).

Now if I add 10 more characters to the text in the first div (forked codepen available here), I see that first div has width of 311.719px while the second div's width is 288.281px.

So it seems that more content gives more width to the flex-item, but how does this content based calculation exactly works? What about when content is not just text but also some replaced content such as images?

Also, should I generally practice to explicitly set flex-basis or width properties to avoid uncertainties of element size that is based on content? In other words, what are use-cases to not set explicitly flex-item's width and leave it off for flexbox to determine it based on its content?

解决方案

For this particular case you need to conisder the default shrink effect set by flex-shrink which has a default value of 1. Initially your element will overflow like below:

$('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>

If you inspect the elements you will have 1011.3px for the first element and 935.3px for the second one so we have a total overflow of 1011.3px + 935.3px - 600px = 1346.6px. This overflow will be reduced from both elements so they can fit inside the flex container. We should also consider that the elements will not shrink the same way since they don't have the same initial width. The biggest one will shrink more. We will then have a factor of 1011.3/935.3 = 1.08 and the formula will be:

x + y = 1346.6 where y = 1.08*x

So x = 647px and y = 699.6px

We will end with 1011.3px - 699.6px = 311.7px and 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>


The flex-shrink property specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed. ref

Note: The flex shrink factor is multiplied by the flex base size when distributing negative space. This distributes negative space in proportion to how much the item is able to shrink, so that e.g. a small item won’t shrink to zero before a larger item has been noticeably reduced. ref

Official Specificiation for the complete algorithm:

https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths


Be aware that there is the min-width constraint that may affect the final calculation since by default an element cannot shrink past its content size.

Here is the same code as above with some &nbsp; and you will notice that the calculation is different because the first element is having a min-width contraint equal to the length of the first sentence where we have the &nbsp;

$('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&nbsp;ipsum&nbsp;dolor&nbsp;sit&nbsp;amet&nbsp;consectetur&nbsp;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>

If you remove this constraint by adding min-width:0 you will get the previous values and some overflow:

$('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&nbsp;ipsum&nbsp;dolor&nbsp;sit&nbsp;amet&nbsp;consectetur&nbsp;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>


What about when content is not just text but also some replaced content such as images?

Same logic apply, it doesn't really matter the type of content, all what matter is the size of the element and the min-width contraint that depend on the content.

Also, should I generally practice to explicitly set flex-basis or width properties to avoid uncertainties of element size that is based on content?

I would say yes. You should have full control over your layout and don't leave the content take the decision for you.

这篇关于如果没有设置 flex-basis 或宽度,flexbox 如何计算 flex-item 的宽度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆