Firefox:Flexbox容器内的项目不保留纵横比

时间:2017-10-20 10:04:31

标签: css firefox flexbox centering css-grid

我在解决another issue的同时遇到了这个问题。
我有以下基本布局:

+-----+-----------------+
|     |                 |
|  c  |c   +------+     |
|  o  |o   | item |     |
|  l  |l   |      |     |
|     |    +------+     |
|  1  |2                |
+-----------------------+

col 1col 2是通过CSS Grid创建的。现在,我正在努力将item(水平和垂直)集中在col 2内。



#content {
  display: grid;
  grid-template-columns: minmax(13rem, 15%) minmax(85%, 100%);
  
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}

#circle {
  background: #7FFF00;
  
  width: 9%;
  padding-top: 9%;
  border-radius: 50%;
  
  margin: auto;
}

.menu {
  background: #D2691E;
  
  grid-row-start: 1;
  grid-row-end: 1;
}

.circle-area {
  background: #191970;
  
  grid-row-start: 1;
  grid-row-end: 1;
  grid-column-start: auto;
  grid-column-end: span 2;
  
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

<body>
<div id='content'>
<div class='menu'></div>
<div class='circle-area'>
<div id='circle'></div>
</div>
</div>
</body>
&#13;
&#13;
&#13;

Code above on JSFiddle

在Chrome 62.0和Safari 11.0中测试时,我的代码正如我所期望的那样(item保存它的纵横比并垂直和水平居中)。虽然我已经使用Firefox(56.0) - 在窗口大小调整时改变了宽高比。我尝试了另一个centering technique - 使用grid (JSFiddle)(结果是同样的Firefox不会保留纵横比)。

现在,来自css的commenting out (JSFiddle) flex部分将使Firefox保留纵横比,尽管item不再垂直居中。

我的问题是:

  1. 这是Firefox中的已知问题(错误),还是我的代码有问题?
  2. 在保留纵横比(最好使用flex )的同时,在item内垂直和水平居中col 2的正确修复/解决方法是什么?

1 个答案:

答案 0 :(得分:2)

基于百分比的垂直边距/填充的浏览器行为简而言之

错误本身,但可能是由于浏览器的不同实现方式基于百分比的垂直间距(顶部和底部边距/填充)应该在flexgrid布局上下文中计算:

  

网格项的边距和填充百分比可以通过以下任一方式解决:

     
      
  • 他们自己的轴(左/右百分比分解宽度,顶部/底部分辨高度),或,
  •   
  • 内联轴(左/右/上/下百分比全部解析宽度)
  •   
     

用户代理必须选择以下两种行为之一。

选择任一分辨率策略都有无一致性:正如您所看到的,Chrome和Safari将选择策略#2,而IE,Edge和Firefox将选择策略#1(其解释你的错误)。 W3C还指出:

  

注意:这种差异很糟糕,但它准确地捕获了当前的世界状态(实现之间没有达成共识,CSSWG内部没有达成共识)。 CSSWG的意图是浏览器会聚合其中一个行为,此时规范将被修改为要求。

     

作者应该完全避免在网格项目中使用填充或边距的百分比,因为它们会在不同的浏览器中获得不同的行为。

解决方案

您可以做的只是将圆圈本身定义为伪元素。在这种方法中:

  • 外部#circle元素的宽度为9%,但没有其他内容
  • ::before伪元素的宽度为100%,填充顶部为100%,这将强制它按需要的宽高比为1:1

您更新的CSS将如下所示:

#circle {
  width: 9%;
  margin: auto;
}

#circle::before {
  background: #7FFF00;
  border-radius: 50%;
  width: 100%;
  height: 0;
  padding-top: 100%;
  content: '';
  display: block;
}

请参阅下面(或fiddle)中的概念验证:

&#13;
&#13;
#content {
  display: grid;
  grid-template-columns: minmax(13rem, 15%) minmax(85%, 100%);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}

#circle {
  width: 9%;
  margin: auto;
}

#circle::before {
  background: #7FFF00;
  border-radius: 50%;
  width: 100%;
  height: 0;
  padding-top: 100%;
  content: '';
  display: block;
}

.menu {
  background: #D2691E;
  grid-row-start: 1;
  grid-row-end: 1;
}

.circle-area {
  background: #191970;
  grid-row-start: 1;
  grid-row-end: 1;
  grid-column-start: auto;
  grid-column-end: span 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
&#13;
<body>
  <div id='content'>
    <div class='menu'></div>
    <div class='circle-area'>
      <div id='circle'></div>
    </div>
  </div>
</body>
&#13;
&#13;
&#13;