微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

css – 填充和边框中的flex-shrink因子如何?

假设我们有一个宽度为400px的flex容器.

这个容器里面有三个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 articleflexbox 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>

jsFiddle demo

问题

然而,当引入填充时,收缩结果是不同的.当填充与框大小: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>

jsFiddle demo

解决方法

Flexbox将此定义为

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

原文地址:https://www.jb51.cc/css/217112.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。