【问题标题】:How flexbox calculates flex-item's width if no flex-basis or width are set?如果没有设置 flex-basis 或 width ,flexbox 如何计算 flex-item 的宽度?
【发布时间】:2019-06-13 23:18:46
【问题描述】:

我想了解当flex-basiswidthmin-widthmax-width 属性未设置显式值时,flexbox 如何计算最终弹性项目的宽度。换句话说,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>

在此示例中,divs(弹性项目)的计算宽度相同:300px(我使用“检查元素”调试工具看到)。

现在,如果我在第一个 div (forked codepen available here) 的文本中再添加 10 个字符,我会看到第一个 div 的宽度为 311.719px,而第二个 div 的宽度为 288.281px

所以看起来更多的内容为弹性项目提供了更多的宽度,但是这种基于内容的计算究竟是如何工作的呢?当内容不仅是文本,还包括一些替换的内容(例如图像)时会怎样?

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

【问题讨论】:

  • 看看这两个链接:basic concepts of flexboxControlling Ratios of Flex Items Along the Main Axis。我认为这在他们之间得到了解释。基本上 - 当弹性基础设置为自动时 - 这意味着查看我的宽度/高度属性。如果未设置,则表示使用内容的大小来确定它们在主轴上的大小
  • 参见stackoverflow.com/questions/34352140/….. 注意默认情况下,flex item 占用与其内容一样多的空间,因为对于 flex item @987654338 @ 是默认值...因为未指定 flex-basis 和尺寸,只有当 flex-items 没有足够的空间时,它们才会像 flex-shrink: 1 那样收缩另一个默认值...

标签: html css flexbox


【解决方案1】:

对于这种特殊情况,您需要考虑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 的总溢出。这两个元素的溢出将被减少,因此它们可以放入弹性容器中。我们还应该考虑元素不会以相同的方式收缩,因为它们没有相同的初始宽度。最大的会缩小更多。然后我们将得到一个因子1011.3/935.3 = 1.08,公式为:

x + y = 1346.6 where 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 {
  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


请注意,min-width 约束可能会影响最终计算,因为默认情况下为 an element cannot shrink past its content size

这里是与上面相同的代码,带有一些&amp;nbsp;,您会注意到计算不同,因为第一个元素的min-width 约束等于我们拥有&amp;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>

如果您通过添加 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&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>

如果内容不仅是文本,还包括一些替换的内容(例如图像),该怎么办?

同样的逻辑适用,内容的类型并不重要,重要的是元素的大小和取决于内容的 min-width 约束。

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

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

【讨论】:

    猜你喜欢
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多