假设我有一个只有两个子元素的弹性容器,我想允许他们缩小,所以我给这两个子元素一个非零值flex-shrink.据我所知,重要的是价值观之间的比例.因此,将这些值设置为:

  • 第一个子元素4,第二个子元素1
  • 第一个子元素100,第二个子元素25
  • 第一个子元素1,第二个子元素0.25

都应该产生相同的行为.确实是这样的.直到其中一个子元素达到min-width岁.在第三种情况下,第二个子级溢出出容器.我会说这是一个漏洞,但在Chrome、Safari和Firefox上都是一致的.

这是一个playground,这是一个屏幕截图,显示了"虫子",其中我添加了每个子元素的衡量标准.每个子width属性设置为200px和min-widthplaygroundpx.容器的宽度在第一种情况下为300px,在第二种情况下为220px.

body {
  background: black;
  color: white;
}

.container {
  border: deeppink 2px solid;
  display: flex;
  height: 50px;
}

.box {
  width: 200px;
  min-width: 100px;
}

.green {
  background: green;
}

.blue {
  background: blue;
}
<h2>First case, both boxes have pixels to give up</h2>
<h3>Flex shrink 4 and 1</h3>
<div class="container" style="width: 300px;">
  <div class="green box" style="flex-shrink: 4;"></div>
  <div class="blue box" style="flex-shrink: 1;"></div>
</div>
<h3>Flex shrink 100 and 25</h3>
<div class="container" style="width: 300px;">
  <div class="green box" style="flex-shrink: 100;"></div>
  <div class="blue box" style="flex-shrink: 25;"></div>
</div>
<h3>Flex shrink 1 and 0.25</h3>
<div class="container" style="width: 300px;">
  <div class="green box" style="flex-shrink: 1;"></div>
  <div class="blue box" style="flex-shrink: 0.25;"></div>
</div>

<h2>Second case, first box is at its minimun</h2>
<h3>Flex shrink 4 and 1</h3>
<div class="container" style="width: 220px;">
  <div class="green box" style="flex-shrink: 4;"></div>
  <div class="blue box" style="flex-shrink: 1;"></div>
</div>
<h3>Flex shrink 100 and 25</h3>
<div class="container" style="width: 220px;">
  <div class="green box" style="flex-shrink: 100;"></div>
  <div class="blue box" style="flex-shrink: 25;"></div>
</div>
<h3>Flex shrink 1 and 0.25: overflow!</h3>
<div class="container" style="width: 220px;">
  <div class="green box" style="flex-shrink: 1;"></div>
  <div class="blue box" style="flex-shrink: 0.25;"></div>
</div>

有人能解释一下这是怎么回事吗?

enter image description here

推荐答案

我会试着用简单的词来总结它正在发生的事情,因为规范的话是噩梦.

你面临的问题与两件事有关.第一个是"修复最小/最大违规".第二个是flex-shrink因数之和小于1.所有内容都在这一部分详细说明:https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths

以下是正在一步步发生的事情.

首先,我们从找到元素的大小开始,注意到我们有一个溢出空间和一个负的自由空间.200px + 200px > 220px,可用空间是180px.

我们计算每一项的"比例伸缩系数",然后我们得到的比率是0.8 = (1 * 200)/(1 * 200 + .25*200)0.2 = (.25 * 200)/(1 * 200 + .25*200)

第一项将缩小.8*180px = 144px,第二项将缩小.2*180px = 36px,这将使新宽度等于56px164px

在此之后,我们将点击"修复最小/最大违规",因为第一项小于其min-width(第二项可以).所以我们把它限制在100pxfreze之间.所有的诀窍都在这里,我们不再接触第一个项目,我们再次运行算法,只考虑第二个项目.

因此,我们的新配置是一个宽度为200px的元素,在等于220px - 100px = 120px的空间内的收缩系数等于0.25.这里有第二件事,收缩因子的和(我们只有一个)小于1,所以我们的项目不会收缩所有负的自由空间.

负的可用空间等于200px - 120px = 80px,但我们不会考虑它,因为如果我们遵循规范,我们可以阅读:

按照上面的初始可用空间计算剩余可用空间.If the sum of the unfrozen flex items’ flex factors is less than one,则将初始可用空间乘以该和.如果此值的大小等于剩余可用空间的大小,则将其用作剩余可用空间.

初始可用空间为180px,因此我们将该值乘以.25,得到45px.该值的大小小于新的空闲空间(剩余的空闲空间等于80px),因此我们使用它.

现在你知道故事的结局了.我们有一个项目需要缩小45px,而不是80px,因此它的最终宽度是155px,我们有一个溢出(155px + 100px > 220px)

这种行为背后的逻辑是在01之间有一种连续函数.0意味着没有收缩,1意味着完全收缩,超过1仍然是完全收缩,但在这两者之间,我们有部分收缩.

下面是一个易于理解的简化示例.

body {
  background: black;
}

.container {
  border: deeppink 2px solid;
  display: flex;
  width: 200px;
  height: 50px;
  margin: 10px 0;
}

.box {
  width: 300px;
  background: green;
}
<div class="container">
  <div class="box" style="flex-shrink: 0;"></div>
</div>
<div class="container">
  <div class="box" style="flex-shrink: 0.2;"></div>
</div>
<div class="container">
  <div class="box" style="flex-shrink: 0.4;"></div>
</div>
<div class="container">
  <div class="box" style="flex-shrink: 0.6;"></div>
</div>
<div class="container">
  <div class="box" style="flex-shrink: 0.8;"></div>
</div>
<div class="container">
  <div class="box" style="flex-shrink: 1;"></div>
</div>
<div class="container">
  <div class="box" style="flex-shrink: 10;"></div>
</div>

如你所见,当我们将值从0增加到1时,减慢的项目会收缩.

对于其他情况,您不会有任何溢出问题,因为即使在冻结某些项目之后,您的收缩系数之和也将等于或大于1,因此我们将始终使用新计算的可用空间

Css相关问答推荐

如何提高数学输出的质量?

转换间隙值时基于百分比的弹性元素&跳转

在COLOR-MIX()中使用var()似乎会使其对于不支持COLOR-MIX()的浏览器具有可读性,从而阻止了回退的工作

此css Select 器的总体特性是什么?按钮:不是(#mainBtn,.cta)

正确的`最小/最大宽度`+`非(设备类型)`css媒体查询的语法

如何减少弹性项目之间的差距

如何更改 JqGrid 中的pager 背景 colored颜色 ?

如何在流线型多页面应用程序中在表情符号和页面名称之间留出一些空白

我无法覆盖 react ui 库中的组件样式

整个列的 CSS Grid Margin Top

如何为使用jsTreeR拖入层次 struct node 的元素添加顺序编号?

位置绝对混乱的 CSS Flexbox

为什么不能将特定于供应商的伪元素/类组合成一个规则集?

使用 CSS 剪辑/裁剪背景图像

删除所有填充和边距表格 HTML 和 CSS

CSS3 box-shadow:inset 可以只做一侧或两侧吗?喜欢边界顶部?

CSS - 使 div 水平对齐

CSS 外边框

如何在页面上居中 twitter bootstrap 选项卡?

输入上方带有标签的样式表