在padding和border-box中flex-shrink factor如何? [英] How does flex-shrink factor in padding and border-box?

查看:107
本文介绍了在padding和border-box中flex-shrink factor如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个宽度为400像素的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。





flex-shrink c $ c> padding 和盒尺寸是否涉及?



DEMO

解决方案

Flexbox 将此定义为




对于行上的每个未冻结项目,将其缩放因子
乘以其内部 flex基本大小,并注意为 缩放flex
shrink factor
。查找项目的缩放的缩放
因子
为所有$ 缩放的缩放因子的总和b $ b未冻结的项目就行了。将该项目的目标主尺寸设置为
flex基本大小减去
剩余可用空间与比率成比例。


简化,冻结的flex项目是不能或不必被弯曲的项目。我将假设没有 min-width 限制和非零flex收缩因子。这样,所有flex项目最初都是未冻结的,并且只有一个flex循环迭代后它们都被冻结。



内部flex基础大小取决于 box-sizing ,由CSS2UI定义



  • content-box 指定的宽度和高度(以及相应的最小/最大值属性)分别适用于元素的
    内容框的宽度和高度。元素的填充和边框是
    ,布局和绘制在指定的宽度和高度之外。


  • border-box :宽度和高度的长度和百分比值)在此元素上确定元素的
    边框框。也就是说,
    上指定的任何填充或边框元素都会在此指定的 width
    height 。内容宽度和高度通过
    计算,从
    减去指定宽度和高度属性的各边的边框和填充宽度。 [...]使用的值,例如通过getComputedStyle()暴露的
    也引用
    边框框。



基本上,这意味着大小(宽度,flex基数)有一个内部变量。内部大小只包括内容,外部大小也包括paddings和边框宽度。在 box-sizing:content-box 的情况下,样式表中指定的长度将用作内部大小,或者在 box-sizing: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 ,所以现在 -260px p>

 (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

使用 -sizing:border-box ,指定的flex基数是外部的,所以paddings从它们中减去计算内部的, 280px 180px 80px 。然后缩放的缩放因子的总和变成 2 * 280px + 180px + 2 * 80px = 900px 。可用空间类似于没有填充的情况,因为外柔性基底是相同的。注意 getComputedStyle 检索的 width 现在将是外部的,所以paddings在末尾添加。 p>

 (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


Let's say we have a flex container with a width of 400px.

Inside this container are three flex items:

: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; }

So the total width of flex items is 600px and the free space in the container is -200px.

With help from this question, this article, and the flexbox spec, I've learned the basic formula for distributing negative free space among flex items:

Step 1

Multiply each shrink value by its basis and add them all together:

:nth-child(1)  2 * 300 = 600
:nth-child(2)  1 * 200 = 200
:nth-child(3)  2 * 100 = 200

TOTAL = 1000

Step 2

Divide each item above by the total to determine the shrink factor:

:nth-child(1)  600 / 1000 = .6
:nth-child(2)  200 / 1000 = .2
:nth-child(3)  200 / 1000 = .2

Step 3

Multiply the shrink factor by the negative free space to determine the space removed from each item:

:nth-child(1)  .6 * -200px = -120px
:nth-child(2)  .2 * -200px =  -40px
:nth-child(3)  .2 * -200px =  -40px

So, the computed size of each flex item should be:

:nth-child(1)  300px - 120px = 180px
:nth-child(2)  200px -  40px = 160px
:nth-child(3)  100px -  40px =  60px

Tested in Chrome, Firefox and IE11, the numbers check out. The calculation works perfectly. DEMO


The Problem

When padding is introduced, however, the shrink results are different. When padding is applied along with box-sizing: border-box, this results in yet another set of numbers.

What's the flex-shrink calculation when padding and box-sizing are involved?

DEMO

解决方案

Flexbox defines this as

For every unfrozen item on the line, multiply its flex shrink factor by its inner flex base size, and note this as its scaled flex shrink factor. Find the ratio of the item’s scaled flex shrink factor to the sum of the scaled flex shrink factors of all unfrozen items on the line. Set the item’s target main size to its flex base size minus a fraction of the absolute value of the remaining free space proportional to the ratio.

Simplifying, frozen flex items are those which can't or don't have to be flexed anymore. I will assume no min-width restrictions and non-zero flex shrink factors. This way all flex items are initially unfrozen and they all become frozen after only one iteration of the flex loop.

The inner flex base size depends on the value of box-sizing, defined by CSS2UI as

  • 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 width and height. 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.

Basically, that means that sizes (widths, flex bases) have an inner an an outer variant. The inner size includes only the content, the outer one also includes paddings and border widths. The length specified in the stylesheet will be used as the inner size in case of box-sizing: content-box, or as the outer one in case of box-sizing: border-box. The other can be calculated by adding or subtracting border and padding widths.

Neglecting lots of details, the algorithm would be something like

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;
}

With no paddings, it's as you explain

                                   (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

With 10px horizontal paddings, the available space is reduced by 3 * 2 * 10px = 60px, so now it's -260px.

                                   (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

When you use box-sizing: border-box, the specified flex bases are the outer ones, so the paddings are subtracted from them to calculate the inner ones, which are 280px, 180px, 80px. Then the sum of the scaled flex shrink factors becomes 2*280px + 180px + 2*80px = 900px. The available space is like in the case with no padding, because the outer flex bases are the same. Note the width retrieved by getComputedStyle will now be the outer one, so paddings are added back at the end.

                                                    (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

这篇关于在padding和border-box中flex-shrink factor如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆