为什么 Chrome 和 Firefox 显示不同的 flex 布局结果? [英] Why do Chrome and Firefox show different flex layout results?

查看:19
本文介绍了为什么 Chrome 和 Firefox 显示不同的 flex 布局结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

为什么会发生这种情况?这是一个错误,还是我遗漏了一些默认值"或差异?

body{背景颜色:青色;}.flexContainer{背景颜色:蓝色;边框:1px纯黑色;高度:300px;}.flexItem{背景颜色:红色;边框:1px纯黑色;}.flexContainer{显示:弹性;flex-flow:行包装;对齐内容:居中;对齐项目:拉伸;对齐内容:flex-start;}.flexItem{弹性:0 1 0;}

<div class="flexItem">1111111111111111111</div><div class="flexItem">2222<br/>2222</div><div class="flexItem">3333<br/>3333<br/>3333</div><div class="flexItem">44444444444444444444</div>

解决方案

问题根源

这里是问题的根源:

.flexContainer {显示:弹性;flex-flow:行包装;对齐内容:居中;对齐项目:拉伸;对齐内容:flex-start;<-- 问题}


背景

align-content 属性控制 flex 容器内 flex lines 的横轴对齐.将 flex 线视为行或列(取决于 flex-direction) 弹性项目所在的位置.换句话说,align-content 分配弹性线之间和周围的空间,将它们打包到顶部、底部、中心等(参见 完整的值列表).

因为align-content伸缩行之间和周围分配空间,所以它只能在多行伸缩容器上工作.(单线延伸到容器的整个横轴长度,没有为 align-content 工作留下可用空间.)

显然,多行容器是多行的容器(flex 项目已包装).然而,从技术上讲,多行容器只是一个带有 的容器flex-wrap: wrapflex-wrap: wrap-reverse(不管 flex 项目是否已经被包裹,甚至是否存在).

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

<块引用>

§ 8.4.包装 Flex Lines:align-content财产

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

§6. Flex线条

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

  • 单行 flex 容器(即带有 flex-wrap: nowrap 的容器)将它的所有子元素放在一行中,即使那样将导致其内容溢出.

  • 一个 多行 flex 容器(即一个带有 flex-wrap: wrapflex-wrap: wrap-reverse) 将它的 flex 项目分成多行,类似于文本太宽而无法容纳在现有行上时如何将其分成新行.


Chrome 和 Firefox/Edge 之间的差异

再次查看您的代码:

body {背景颜色:青色;}.flexContainer {背景颜色:蓝色;边框:1px纯黑色;高度:300px;}.flexItem {背景颜色:红色;边框:1px纯黑色;}.flexContainer {显示:弹性;flex-flow:行包装;对齐内容:居中;对齐项目:拉伸;对齐内容:flex-start;}.flexItem {弹性:0 1 0;}

<div class="flexItem">1111111111111111111</div><div class="flexItem">2222<br/>2222</div><div class="flexItem">3333<br/>3333<br/>3333</div><div class="flexItem">44444444444444444444</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,这在技术上创建了一个多行 flex 容器,就 Firefox 和 Edge 而言.弹性项目的实际包装或存在无关紧要.

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

<块引用>

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

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

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


标准合规

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

但是,我不会将 Chrome 的行为描述为错误".他们所做的更有可能是干预.

<块引用>

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

干预似乎是 Chrome 的标准做法.示例:


更多信息

When there is only one row of "flex items", Chrome and Firefox show different results. When there is more than one line(wrap), Chrome and Firefox show the same result!

So why is this happening? Is that a bug, or is there some "default value" or difference that I am missing?

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>

解决方案

Source of the Problem

Here is the source of the problem:

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


Background

The align-content property controls the cross-axis alignment of flex lines within the flex container. Think of flex lines as the rows or columns (depending on flex-direction) in which flex items live. Put another way, align-content distributes the space between and around flex lines, packing them to the top, bottom, center, etc. (see the full list of values).

Because align-content distributes space between and around flex lines, it can only work on multi-line flex containers. (A single-line extends across the full cross-axis length of the container leaving no free space for align-content to work.)

Obviously, a multi-line container is a container with more than one line (flex items have wrapped). Technically, however, a multi-line container is simply a container with flex-wrap: wrap or flex-wrap: wrap-reverse (regardless of whether flex items have wrapped, or even exist).

Same concept applies to a single-line flex container, which is a container with flex-wrap: nowrap. The align-content property has no effect in nowrap containers, as discussed above.

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

The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis. Note, this property has no effect on a single-line flex container.

§ 6. Flex Lines

Flex items in a flex container are laid out and aligned within flex lines, hypothetical containers used for grouping and alignment by the layout algorithm. A flex container can be either single-line or multi-line, depending on the flex-wrap property:

  • A single-line flex container (i.e. one with flex-wrap: nowrap) lays out all of its children in a single line, even if that would cause its contents to overflow.

  • A multi-line flex container (i.e. one with flex-wrap: wrap or flex-wrap: wrap-reverse) breaks its flex items across multiple lines, similar to how text is broken onto a new line when it gets too wide to fit on the existing line.


The Discrepancy between Chrome and Firefox / Edge

Looking again at your code:

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>

Notice three things:

(1) There is no actual wrapping. All four items exist on one line. The flex container has one line.

(2) The flex-wrap property is set to wrap (in the flex-flow shorthand).

(3) The align-content property is set to flex-start.

Let's break this down.

Because there is only a single line in the flex container, Chrome is ignoring align-content. As written in the specification (see above):

The align-content property has no effect on a single-line flex container.

So this is Chrome's interpretation. If there is an actual single line, then ignore align-content.

Switch between wrap and nowrap in Chrome. There's no difference.

On the other hand, because the container is set to flex-wrap: wrap, this technically creates a multi-line flex container, as far as Firefox and Edge are concerned. The actual wrapping or existence of flex items is irrelevant.

As written in the specification (see above):

A multi-line flex container (i.e. one with flex-wrap: wrap or flex-wrap: wrap-reverse) breaks its flex items across multiple lines...

Switch between wrap and nowrap in Firefox and Edge. There's a difference.

So each browser has it's own way of implementing this rendering behavior.


Standards Compliance

In terms of adherence to the specification, I would say that Firefox and Edge are at full compliance. They seem to adhere most closely to the wording in the spec.

However, I wouldn't characterize Chrome's behavior as a "bug". What they've done is more likely an intervention.

An intervention is when a user agent decides to deviate slightly from a standardized behavior in order to provide a greatly enhanced user experience.

Interventions appear to be standard practice at Chrome. Examples:


More Information

这篇关于为什么 Chrome 和 Firefox 显示不同的 flex 布局结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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