为什么Chrome和Firefox显示不同的Flex布局结果?

时间:2018-09-11 19:39:28

标签: css css3 google-chrome firefox flexbox

当只有一行“弹性项目”时,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>

1 个答案:

答案 0 :(得分:2)

问题的根源

这是问题的根源:

.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线之间和周围分配空间,因此它只能在 multi-line 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容器的行对齐   当横轴上有多余空间时,伸缩容器   类似于justify-content将单个项目对齐   主轴。 请注意,此属性对单行伸缩没有影响   容器

     

§ 6. Flex Lines

     将

flex容器中的flex项目放置并在 flex中对齐   行,假设容器用于分组和对齐   布局算法。 flex容器可以是单行或   多行,具体取决于flex-wrap属性:

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

  •   
  • 一个多行伸缩容器(即一个带有flex-wrap: wrapflex-wrap: wrap-reverse的伸缩容器)将其伸缩项目分成多行,类似于将文本拆分为多行当新行太宽而无法容纳现有行时,会显示一条新行。

  •   

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属性对单行伸缩容器没有影响

这就是Chrome的解释。如果实际只有一行,则忽略align-content

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

另一方面,由于容器设置为flex-wrap: wrap,因此从技术上讲,就Firefox和Edge而言,这将创建多行flex容器。弹性物品的实际包装或存在与否无关。

如规范中所述(请参见上文):

  

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

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

因此每种浏览器都有实现这种渲染行为的独特方式。


符合标准

在遵守规范方面,我要说Firefox和Edge完全兼容。他们似乎最遵守规范中的措辞。

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

  

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

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


更多信息