flexbox - 当弹性项目具有不同的弹性基础时如何计算弹性收缩

标签 flexbox

假设我有一个简单的 flex 容器,其中包含 2 个 flex 项,其中 flex 项的大小超过了容器的大小 - 将使用 flex-shrink ......就像这样:

.container {
  width: 600px;
  outline: 5px solid;
  display: flex;
}
section {
  flex: 0 1 600px;
  background: salmon;
}
aside {
  flex: 0 1 200px;
  background: aqua;
}
<div class="container">
  <section>
    <h2>Main content here</h2>
  </section>
  <aside>
    <h2>Some side content</h2>
  </aside>
</div>


Codepen demo

在上面的例子中:容器是 600px,部分 flex-item 的 flex-basis 是 600px,而 side 的 flex-basis 是 200px - 所以负空间是 200px。

因此,两个弹性项目都具有相同的 flex-shrink 因子 1 - 我预计两个弹性项目都会使用 section 收缩 100 像素获得 600px - 100px = 500px 的宽度和 aside得到 200px - 100px = 100px

但结果实际上是 section缩小 150px 到 450px 和 aside缩小 50px 到 150px

于是我看了the spec我发现了这个:

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.



所以现在我明白了,在计算 flex 项目的 flex-shrink 时,不仅要考虑 flex 收缩因子,还要考虑 flex 基本大小(这里,由 flex-basis 属性定义)

问题是我似乎无法通过数学来计算 flex-shrink。

所以继续上面的例子:假设我改变了 section 的收缩因子到 2...

.container {
  width: 600px;
  outline: 5px solid;
  display: flex;
}
section {
  flex: 0 2 600px;
  background: salmon;
}
aside {
  flex: 0 1 200px;
  background: aqua;
}
<div class="container">
  <section>
    <h2>Main content here</h2>
  </section>
  <aside>
    <h2>Some side content</h2>
  </aside>
</div>


Codepen demo #2

...结果是 section获得 428px 的宽度和 aside宽度为 121px

有人可以解释如何计算吗?

最佳答案

忽略很多细节,算法是这样的

let sumScaledShrinkFactors = 0,
    remainingFreeSpace = flexContainer.innerMainSize;
for (let item of flexItems) {
  remainingFreeSpace -= item.outerFlexBasis;
  item.scaledShrinkFactor = item.innerFlexBasis * item.flexShrinkFactor;
  sumScaledShrinkFactors += item.scaledShrinkFactor;
}
for (let item of flexItems) {
  let ratio = item.scaledShrinkFactor / sumScaledShrinkFactors;
  item.innerWidth = item.innerFlexBasis + ratio * remainingFreeSpace;
}

所以公式就像
flexBasis * (1 + shrinkFactor / sumScaledShrinkFactors * remainingFreeSpace)

第一个案例
1*600px + 1*200px ─┐               width 
                   │              ───────
600px * (1 + 1 / 800px * -200px) = 450px 
200px * (1 + 1 / 800px * -200px) = 150px 
                            │     ───────
600px - (600px + 200px) ────┘      600px 

第二种情况
2*600px + 1*200px ──┐               width 
                    │              ───────
600px * (1 + 2 / 1400px * -200px) ≈ 429px 
200px * (1 + 1 / 1400px * -200px) ≈ 171px 
                             │     ───────
600px - (600px + 200px) ─────┘      600px 

关于flexbox - 当弹性项目具有不同的弹性基础时如何计算弹性收缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36550840/

相关文章:

html - 如何修复 Web 组件以获取滚动条?

html - 具有未定义列数的网格布局

html - flex 元素在换行时应该左对齐,而不是居中

css - PhoneGap 对 FlexBox 模型的支持

html - 在不向父级提供高度的情况下在 flex 列中排列元素

html - Angular Flex 布局 : Responsive layout combining row and column

html - 在 REACT 中使用 CSS

html - 如何垂直对齐和拉伸(stretch) flexbox 元素的子元素?

css - flex 元素垂直显示,实际上不会 "flex"

html - 为什么我的 flex 元素没有包装?