为啥 Chrome 和 Firefox 显示不同的 flex 布局结果?

Posted

技术标签:

【中文标题】为啥 Chrome 和 Firefox 显示不同的 flex 布局结果?【英文标题】:Why do Chrome and Firefox show different flex layout results?为什么 Chrome 和 Firefox 显示不同的 flex 布局结果? 【发布时间】:2019-02-16 09:10:48 【问题描述】:

当只有一行“flex items”时,Chrome 和 Firefox 显示不同的结果。当多于一行时(换行),Chrome 和 Firefox 显示相同的结果!

那么为什么会这样呢?这是一个错误,还是我缺少一些“默认值”或差异?

body
    background-color: teal;


.flexContainer
    background-color: blue;
    border: 1px solid black;
    height: 300px;

.flexItem
    background-color: red;
    border: 1px solid black;


.flexContainer
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: stretch;
    align-content: flex-start;


.flexItem 
    flex: 0 1 0; 
<div class="flexContainer">
    <div class="flexItem">1111111111111111111</div>
    <div class="flexItem">2222<br/>2222</div>
    <div class="flexItem">3333<br/>3333<br/>3333</div>
    <div class="flexItem">4444444444444444444</div>
</div>

【问题讨论】:

因为align-content 它仍然是一个草稿。 drafts.csswg.org/css-flexbox-1/#align-content-property 如果我理解,对于单行,它不应该被应用,除非需要前缀,否则 chrome 会做预期的事情......确实不清楚会发生什么,但规则也不是候选......跨度> 【参考方案1】:

问题的根源

这是问题的根源:

.flexContainer 
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: stretch;
    align-content: flex-start; <-- problem


背景

align-content 属性控制 flex 容器内 flex 线 的横轴对齐方式。将弹性线视为弹性项目所在的行或列(取决于flex-direction)。换句话说,align-content 分配柔性线之间和周围的空间,将它们打包到顶部、底部、中心等(参见 full list of values)。

因为align-content 分配空间 flex 行之间和周围,它只能在多行 flex 容器上工作。 (一条单线延伸到容器的整个横轴长度,没有空间供align-content 工作。)

显然,多行容器是包含多行的容器(弹性项目已包装)。然而,从技术上讲,多行容器只是一个带有flex-wrap: wrap or flex-wrap: wrap-reverse 的容器(无论弹性项目是否已包装,甚至是否存在)。

同样的概念适用于单行 flex 容器,它是一个带有flex-wrap: nowrap 的容器。 align-content 属性在 nowrap 容器中无效,如上所述。

§ 8.4. Packing Flex Lines: the align-content property

align-content 属性对齐 flex 容器的行 当横轴有额外空间时的 flex 容器, 类似于 justify-content 在 主轴。 注意,这个属性对单行 flex 没有影响 容器

§ 6. Flex Lines

flex 容器中的 Flex 项目在 flex 内布局和对齐 行,用于分组和对齐的假设容器 布局算法。弹性容器可以是单行的,也可以是 多行,取决于flex-wrap 属性:

单行 flex 容器(即带有 flex-wrap: nowrap 的容器)将其所有子容器布置在一行中,即使这样会 导致其内容溢出。

多行 flex 容器(即一个带有 flex-wrap: wrapflex-wrap: wrap-reverse 的容器)将其 flex 项拆分为多行,类似于文本被拆分到新行时的方式宽以适应现有线。


Chrome 与 Firefox / Edge 的差异

再次查看您的代码:

body 
  background-color: teal;


.flexContainer 
  background-color: blue;
  border: 1px solid black;
  height: 300px;


.flexItem 
  background-color: red;
  border: 1px solid black;


.flexContainer 
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  align-items: stretch;
  align-content: flex-start;


.flexItem 
  flex: 0 1 0;
<div class="flexContainer">
  <div class="flexItem">1111111111111111111</div>
  <div class="flexItem">2222<br/>2222</div>
  <div class="flexItem">3333<br/>3333<br/>3333</div>
  <div class="flexItem">4444444444444444444</div>
</div>

注意三件事:

(1) 没有实际的包装。所有四个项目都存在于一行中。 flex 容器只有一行。

(2) flex-wrap 属性设置为 wrap(在 flex-flow 简写中)。

(3) align-content 属性设置为flex-start

让我们分解一下。

因为 flex 容器中只有一行,Chrome 忽略了align-content。如规范中所述(见上文):

align-content 属性对单行 flex 容器没有影响

所以这是 Chrome 的解释。如果有实际的单行,则忽略align-content

在 Chrome 中在 wrapnowrap 之间切换。没有区别。

另一方面,因为容器被设置为flex-wrap: wrap,这在技术上创建了一个多行的弹性容器,就 Firefox 和 Edge 而言。弹性项目的实际包装或存在是无关紧要的。

如规范中所写(见上文):

一个多行 flex 容器(即带有 flex-wrap: wrapflex-wrap: wrap-reverse 的容器)将其 flex 项跨越多行...

在 Firefox 和 Edge 中在 wrapnowrap 之间切换。有区别。

所以每个浏览器都有自己的方式来实现这种渲染行为。


标准合规性

在遵守规范方面,我想说 Firefox 和 Edge 完全符合规范。它们似乎最符合规范中的措辞。

但是,我不会将 Chrome 的行为描述为“错误”。他们所做的更可能是intervention

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

干预似乎是 Chrome 的标准做法。例子:

Why don't flex items shrink past content size? flex-shrink discrepancy between Firefox and Chrome Why are percentage heights working on children when the parent has no height defined? pseudo element not aligning at top left corner Google Chrome viewport-anchored expand direction with flexbox How to make images stay within the rows of a css grid container? Flex items overlapping in Chrome and IE11 Why is content overflowing in flexbox? Prevent flex item from exceeding parent height and make scroll bar work Prevent flex item from exceeding parent height and make scroll bar work Vertical spacing difference in Chrome v Firefox using flexbox column wrap

更多信息

How does flex-wrap work with align-self, align-items and align-content?

【讨论】:

Chrome 的 flexbox-specific 干预为零。如果您遇到 Chrome 和 Firefox 以不同方式呈现 flexbox 并且找不到现有的相关错误的情况,请在crbug.com/new 提交一个新的,并带有最小的复制案例。 我想向 Chrome 团队提出疑问。有很多情况(上面列出了一些)Chrome 偏离了 flexbox 规范,我认为它们是干预措施。我不认为他们会都是错误。 我仍然不清楚为什么 Firefox 在遵守 flexbox 标准方面几乎一直领先于 Chrome。 最好讨论 IRL 的历史原因。但今年我们与 Firefox 团队和一些致力于 Webkit 的开源贡献者一起致力于跨浏览器 flex 规范的遵守。您可以在wpt.fyi/compat2021?feature=css-flexbox 看到我们的进展

以上是关于为啥 Chrome 和 Firefox 显示不同的 flex 布局结果?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Firefox 对待 Helvetica 和 Chrome 的方式不同?

为啥 Chrome 和 Firefox 使用基本身份验证的 CORS ajax 调用的行为不同?

为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?

为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?

为啥这个 HTML 在 Google Chrome 和 Firefox 中会产生两种不同的结果?

为啥 Chrome 或 Firefox 不显示待处理请求的请求标头?