Firefox 和 Chrome 之间的 flex-shrink 差异

Posted

技术标签:

【中文标题】Firefox 和 Chrome 之间的 flex-shrink 差异【英文标题】:flex-shrink discrepancy between Firefox and Chrome 【发布时间】:2018-09-09 13:53:02 【问题描述】:

以下简化的代码示例在 Firefox 和 Chrome 上的呈现方式不同。这是浏览器错误的结果吗?如果是,哪个是按规范呈现的,哪个不是?

如果有的话,我想获得一个错误报告的链接。

现在,出于我的目的,在这个简化的示例中添加flex-shrink: 0:导航栏,解决了问题,但我想知道一旦错误可能得到修复,这在未来是否也可以工作......

#fixed 
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;


#tall 
  height: 300%;


.outline 
  outline: 1px solid red;
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />

<div id="fixed" class="d-flex flex-column">
  <nav class="navbar outline">
    <a class="btn btn-secondary">Button</a>
  </nav>
  <div id="tall"></div>
</div>

【问题讨论】:

【参考方案1】:

flex-shrink Firefox 和 Chrome 之间的差异

存在差异,但 flex-shrink 似乎不是原因。

这是浏览器错误的结果吗?如果是,哪个是按照规范呈现的,哪个不是?

这似乎不是一个错误。它看起来更像是一种干预,是故意偏离规范,并且正在被 Chrome 应用。


flex-shrink: 1

弹性容器的初始设置是flex-shrink: 1,由flexbox spec 定义。这意味着允许弹性项目收缩以避免溢出容器。

Chrome 和 Firefox 都遵守此指南。您可以在开发人员工具中通过检查浏览器的弹性项目默认样式来验证这一点。 Chrome 和 Firefox 都使用 flex-shrink: 1 呈现您的弹性项目。

更多详情见:How does flex-shrink factor in padding and border-box?


min-height: auto

列方向容器中弹性项目的初始设置是min-height: auto。在行方向容器中,项目设置为min-width: auto。这意味着弹性项目的默认最小尺寸是其内容的尺寸或沿主轴指定的长度。

更多详情请见:Why don't flex items shrink past content size?


您的代码

你有一个列方向的弹性容器,其中包含两个弹性项目:.navbar#tall。在 Chrome 和 Firefox 中,这两个项目默认设置为 flex-shrink: 1min-height: auto。我使用开发工具验证了这一点。到目前为止一切看起来都不错;所有设置均符合规范。

这是差异的开始: #tall 项目设置为 height: 300%。这个项目比容器高得多。但是,flex-shrink: 1 不会出现溢出。所有具有非零flex-shrink 的项目都必须减小它们的大小,以防止它们自己和它们的兄弟姐妹溢出容器(假设内容的大小允许这样做)。但是使用min-height: auto,项目不能将它们的大小缩小到其内容的高度以下。

所有这些都可以在 Firefox 中使用。但为什么不在 Chrome 中呢?为什么被#tall 挤压的.navbar 项目在Chrome 中缩小到小于其内容(按钮)的大小?


火狐

如上所述,带有height: 300%#tall 元素不能因为flex-shrink 而溢出容器。由于flex-shrink,它的兄弟.navbar 项也必须缩小。但是,由于min-height: auto,它不能缩小低于其内容的大小。都好。一切都符合规范。


与 Firefox 中一样,#tall 元素,带有 height: 300%,不会因为 flex-shrink 而溢出容器。由于flex-shrink,它的兄弟.navbar 项也必须缩小。但是,由于min-height: auto,它不应该缩小低于其内容的大小,但它还是会这样做。为什么?


干预

intervention 是指用户代理决定稍微偏离标准化行为以提供显着增强的用户体验。

来源:https://github.com/WICG/interventions

来自my answer here:

至少从 2017 年开始,Chrome 似乎要么 (1) 恢复到 min-width: 0 / min-height: 0 默认值,要么 (2) 在某些情况下基于神秘算法自动应用 0 默认值。 (这可能是他们所说的intervention。)因此,许多人看到他们的布局(尤其是所需的滚动条)在 Chrome 中按预期工作,但在 Firefox / Edge 中却没有。

因此,如本答案开头所述,您遇到的问题可能不是错误,而是故意偏离规范。完全符合规范的应该是 Firefox。


重要提示

请务必注意,我对 Chrome、Firefox 或任何其他浏览器的内部运作没有直接的了解。我只相信 Chrome 正在根据我的个人观察应用min-height 干预。这是一个理论。更像是外推。有可能我并不完全正确(甚至完全不正确?)。 Chrome 可能会摆弄min-heightflex-shrink 和/或其他属性。我不确定。

还需要注意的是,由于此行为不符合规范,因此它可能不可靠并且可能随时更改。

【讨论】:

Chrome 72(2019 年 1 月发布)中已修复此问题。 Flexbugs 在 Item #1 下提到了它(不支持的 flex 项目的最小内容大小

以上是关于Firefox 和 Chrome 之间的 flex-shrink 差异的主要内容,如果未能解决你的问题,请参考以下文章

在 Chrome、Safari 和 Edge 中显示 flex 对齐不正确,但在 Firefox 中正确

Flex 基础 100% 在列 flexbox 中:Firefox 中的全高,而不是 Chrome

Firefox 和 Chrome 中 Flexbox 的不同实现

flex-end和end之间的区别?

flex和box兼容性写法

Flex 高度在 Chrome 中不起作用 [重复]