【问题标题】:How to calculate flex shrink when flex items have a different flex basis当弹性项目具有不同的弹性基础时如何计算弹性收缩
【发布时间】:2016-08-01 17:48:12
【问题描述】:

假设我有一个简单的 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,section flex-item 的 flex-basis 为 600px,aside 的 flex-basis 为 200px - 所以负空间为 200px。

因此,两个 flex 项具有相同的 flex-shrink 因子 1 - 我预计两个 flex 项会缩小 100px,section 的宽度为 600px - 100px = 500px,aside 的宽度为 200px - 100 像素 = 100 像素

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

然后我查看了the spec,发现了这个:

注意:flex 收缩系数乘以 flex 基本尺寸时 分配负空间。这将负空间分布在 与物品能够收缩的程度成比例,例如一种 在较大的项目之前,小项目不会缩小到零 明显减少。

所以现在我明白了,在计算 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 的宽度

有人能解释一下如何计算吗?

【问题讨论】:

  • 我会使用 %.比如 60% 和 40% 或者你认为应该分开的比例
  • 这可以帮助你理解计算:stackoverflow.com/q/34753491/3597276
  • @Michael_B 谢谢,flex-shrink 似乎比 flex-grow 更复杂,但实际计算中似乎没有太多关于它的信息/博客文章....+1
  • @Danield,同意。根据我的经验,flex-shrinkflex-grow 更复杂。这个问题以及@Oriol(这里和那里)的答案有助于解决这个问题。干杯!

标签: flexbox


【解决方案1】:

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

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 

【讨论】:

  • 我们怎么能记住这个:(
猜你喜欢
  • 2019-09-27
  • 2014-08-09
  • 1970-01-01
  • 2021-07-10
  • 2020-06-16
  • 2017-01-21
  • 2018-06-26
  • 1970-01-01
  • 2019-09-01
相关资源
最近更新 更多