这个容器里面有三个flex项目:
:nth-child(1) { flex: 0 2 300px; } /* flex-grow,flex-shrink,flex-basis */ :nth-child(2) { flex: 0 1 200px; } :nth-child(3) { flex: 0 2 100px; }
因此,Flex项目的总宽度为600px,容器中的可用空间为-200px.
在this question,this article和flexbox spec的帮助下,我学习了在Flex项目之间分配负可用空间的基本公式:
步骤1
将每个收缩值乘以其基础并将它们全部加在一起:
:nth-child(1) 2 * 300 = 600 :nth-child(2) 1 * 200 = 200 :nth-child(3) 2 * 100 = 200
TOTAL = 1000
第2步
将每个项目除以总数以确定收缩因子:
:nth-child(1) 600 / 1000 = .6 :nth-child(2) 200 / 1000 = .2 :nth-child(3) 200 / 1000 = .2
步骤3
将收缩因子乘以负可用空间以确定从每个项目移除的空间:
:nth-child(1) .6 * -200px = -120px :nth-child(2) .2 * -200px = -40px :nth-child(3) .2 * -200px = -40px
因此,每个flex项目的计算大小应该是:
:nth-child(1) 300px - 120px = 180px :nth-child(2) 200px - 40px = 160px :nth-child(3) 100px - 40px = 60px
在Chrome,Firefox和IE11测试中,数字查看.计算工作完美.
.flex { display: flex; width: 400px; height: 50px; margin: 0; padding: 0; list-style: none; text-align: center; } .flex li:nth-child(1) { flex: 0 2 300px; background: orange; } .flex li:nth-child(2) { flex: 0 1 200px; background: chartreuse; } .flex li:nth-child(3) { flex: 0 2 100px; background: aqua; }
<ul class="flex1 flex"> <li>180px</li> <li>160px</li> <li>60px</li> </ul>
问题
然而,当引入填充时,收缩结果是不同的.当填充与框大小:border-Box一起应用时,这将导致另一组数字.
涉及填充和尺寸调整时的flex-shrink计算是什么?
.flex { display: flex; width: 400px; height: 50px; margin: 0; padding: 0; list-style: none; text-align: center; border-bottom: 1px solid #ccc; } .flex li:nth-child(1) { flex: 0 2 300px; background: orange; } .flex li:nth-child(2) { flex: 0 1 200px; background: chartreuse; } .flex li:nth-child(3) { flex: 0 2 100px; background: aqua; } .flex2 li { padding: 0 10px; } .flex3 li { padding: 0 10px; Box-sizing: border-Box; }
<ul class="flex1 flex"> <li>180px</li> <li>160px</li> <li>60px</li> </ul> <ul class="flex2 flex"> <li>144px</li> <li>148px</li> <li>48px</li> </ul> <ul class="flex3 flex"> <li>175.5px</li> <li>160px</li> <li>64.4px</li> </ul>
解决方法
For every unfrozen item on the line,multiply its flex shrink factor
by its inner 07001,and note this as its scaled flex
shrink factor. Find the ratio of the item’s 07002 to the sum of the 07003 of all
unfrozen items on the line. Set the item’s 07004 to
its 07001 minus a fraction of the absolute value of the
07006 proportional to the ratio.
简化,冻结的柔性物品是不能或不必被弯曲的物品.我将假设没有最小宽度限制和非零弹性收缩因子.这样一来,所有的flex项目最初都被解冻,并且它们在Flex循环只有一次迭代之后就被冻结了.
内部flex基础大小取决于由CSS2UI定义的box-sizing
的值
content-Box
: The specified width and height (and respective min/max properties) apply to the width and height respectively of the
content Box of the element. The padding and border of the element are
laid out and drawn outside the specified width and height.
border-Box
: Length and percentages values for width and height (and respective min/max properties) on this element determine the
border Box of the element. That is,any padding or border specified on
the element is laid out and drawn inside this specified 07008
and 07009. The content width and height are calculated by
subtracting the border and padding widths of the respective sides from
the specified width and height properties. […] Used values,as
exposed for instance through getComputedStyle(),also refer to the
border Box.
基本上,这意味着尺寸(宽度,弯曲基座)具有内部的外部变体.内部尺寸仅包含内容,外部尺寸也包括填充和边框宽度.在样式表中指定的长度将用作框大小的内部大小:content-Box,或者在框大小:border-Box的情况下用作外部尺寸.另一个可以通过添加或减少边框和填充宽度来计算.
忽略很多细节,算法就像这样
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; }
没有paddings,这是你解释
(width) innerW │ padd │ outerW ───────┼──────┼─────── 300px * (1 + 2 / 1000px * -200px) = 180px │ 0px │ 180px 200px * (1 + 1 / 1000px * -200px) = 160px │ 0px │ 160px 100px * (1 + 2 / 1000px * -200px) = 60px │ 0px │ 60px ───────┼──────┼─────── 400px │ 0px │ 400px
使用10px水平paddings,可用空间减少3 * 2 * 10px = 60px,所以现在是-260像素.
(width) innerW │ padd │ outerW ───────┼──────┼─────── 300px * (1 + 2 / 1000px * -260px) = 144px │ 20px │ 164px 200px * (1 + 1 / 1000px * -260px) = 148px │ 20px │ 168px 100px * (1 + 2 / 1000px * -260px) = 48px │ 20px │ 68px ───────┼──────┼─────── 340px │ 60px │ 400px
当您使用Box-sizing:border-Box时,指定的flex基数是外部的,所以从它们中减去padd,以计算内部的值,它们是280px,180px,80px.然后缩放的缩放因子的总和变为2 * 280px 180px 2 * 80px = 900px.可用的空间就像没有填充的情况一样,因为外部的柔性基座是相同的.注意,getComputedStyle检索的宽度现在将是外部的宽度,所以在末尾添加paddings.
(width) innerW │ padd │ outerW ────────┼──────┼──────── 280px * (1 + 2 / 900px * -200px) ≈ 155.6px │ 20px │ 175.6px 180px * (1 + 1 / 900px * -200px) = 140.0px │ 20px │ 160.0px 80px * (1 + 2 / 900px * -200px) ≈ 44.4px │ 20px │ 64.4px ────────┼──────┼──────── 340.0px │ 60px │ 400.0px