Firefox 和 Chrome 中 Flexbox 的不同实现

Posted

技术标签:

【中文标题】Firefox 和 Chrome 中 Flexbox 的不同实现【英文标题】:Different implementation of Flexbox in Firefox and Chrome 【发布时间】:2019-07-25 04:01:04 【问题描述】:

以下代码在 Firefox 中按预期工作,但在 Chrome 中,图像变得比 flex 容器大得多。

.r 
  width: 100%;
  height: auto;
  min-width: unset;
  max-width: 100%;


.container 
  display: flex;
  width: 600px;
<div class="container">
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
</div>

火狐

Chrome

【问题讨论】:

试试 .r max-width: 100%;高度:自动 始终避免将 img 作为弹性项目,将它们包裹在弹性项目内 @TemaniAfif 但这并不是真正的解决方案。我只是想知道为什么有两种不同的实现 多么令人失望的结果。 【参考方案1】:

以下代码在 Firefox 中按预期工作

我不同意这一点,因为对我来说,Chrome 的行为符合预期有两个原因:

    您将图像的宽度设置为100%,这意味着它们包含由600px 定义的块(容器)的100%。所以每张图片都是600px

    由于默认的min-width 配置,图像不能shrink past its content size(请注意,在这种情况下使用unset is equivalent to initial,所以它在某种程度上是无用的)。所以图片会保存在600px

如果添加min-width:0,图像只会缩小宽度:

.r 
  width: 100%;
  /*height: auto; useless */
  min-width: 0;
  max-width: 100%;


.container 
  display: flex;
  width: 600px;
<div class="container">
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
</div>

chrome 的行为似乎已经改变,因此在上一个版本中不再需要以下内容

现在,如果我们考虑您所面临的stretch 效果的高度,这在两个浏览器中也不相同。解释起来有点棘手1,但是如果您更改默认对齐方式,您将在 chrome 中获得预期的结果:

.r 
  width: 100%;
  /*height: auto; useless */
  min-width: 0;
  max-width: 100%;


.container 
  display: flex;
  width: 600px;
  align-items:flex-start;
<div class="container">
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
</div>

或者,如果您使用百分比值 you will make it fail 更改高度并且还拥有您想要的(这有点 hacky,因为我们正在触发另一个问题来修复实际问题)

.r 
  width: 100%;
  height:658%; /*any value here with %*/
  min-width: 0;
  max-width: 100%;


.container 
  display: flex;
  width: 600px;
<div class="container">
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
  <img src="https://via.placeholder.com/1000x500" class="r" >
</div>

为什么 Firefox 会这样?

我也不清楚,但合乎逻辑的解释是,Firefox 没有考虑默认的min-width 配置,而是优先考虑保持比例而不是拉伸效果。


1 最初,您的图像定义了容器的高度,因为它们很大(大约 700 像素高度),容器使用此高度,然后我们应用我们的图像的属性,因此它们的宽度会缩小,并且由于默认对齐方式是拉伸,它们将拉伸到最初由它们自己的初始高度定义的容器的高度,从而创建这个渲染。

如果我们移除拉伸效果,图像will try to keep their ratio 因为我们移除了高度限制。

如果我们考虑高度的百分比值,则相同的逻辑。这将失败auto,我们回到默认行为(保持纵横比)


另一种选择

这个问题是由于使用了替换元素的图像而产生的,其中宽度/高度的计算不像其他元素那么简单。

为避免这种行为,最好将图像包裹在 div 中,并避免将它们作为弹性项目。

.r 
  width: 100%;
  max-width: 100%;


.container 
  display: flex;
  width: 600px;


img 
  max-width: 100%;
<div class="container">
  <div class="r"><img src="https://via.placeholder.com/1000x500"></div>
  <div class="r"><img src="https://via.placeholder.com/1000x500"></div>
  <div class="r"><img src="https://via.placeholder.com/1000x500"></div>
  <div class="r"><img src="https://via.placeholder.com/1000x500"></div>
</div>

【讨论】:

@TermaniAfif 感谢您的解释。所以实际上是 Firefox 错误地实现了它。谁知道:/感谢您提供的信息! @TheRuler 我不会称之为错误,但我们遇到了一些不一样的特殊情况。可能在将来它会得到纠正,所以我们有相同的行为 是的,用错词了——我的意思是不同的。再次感谢! @TheRuler 我添加了另一种方法来解释我之前添加额外 div 的评论【参考方案2】:

@TheRuler,最好的解决方案是将图像标签包装在 div 或 span 中,以按照 Firefox 呈现图像。如果您将图像包装在 div 或 span 中,Firefox 也可以正常工作。

现在你可以问我为什么这是正确的。

基本上 display flex 附加了默认值,它们是:

flex-grow: 0
flex-shrink: 1
flex-basis: auto
flex: 0 1 auto /* Shorthand */

现在,对于 Firefox 和 Chrome,默认值是相同的。但是在两个浏览器中的渲染仍然不同,特别是在图像作为 flex child 的情况下。

现在谁是正确的值得商榷,谁正确地遵循准则也值得商榷。

如果你看一下 flex 的规范,它会说,flex 规则应该优先于 CSS 的 width 和 height 属性。所以在这种情况下,Firefox 正在缩小图像的大小以使其适合 600px 父级。

现在如果你看到这个例子,

.container  display: flex; flex-direction: column;
.container > div  flex: 1; height: 300px;

<div class="container">
  <div>Single line in Firefox, but 300px tall in Chrome!</div>
</div>

因此,如果您在两个浏览器中都看到此代码,您将看到不同之处。 Chrome 重视 flex 子项的 height 属性,而 Firefox 不重视它。图像高度和图像宽度也是如此。 Chrome 不占高度。

所以两个浏览器都有自己的实现,在这种情况下不匹配,谁是正确的值得商榷。

因此将它们包装在 span 或 div 中以使其在两个浏览器中都可以正常工作,这应该是正确的答案,没有 hack。其他解决方案可以解决问题,但它们是解决问题的一种技巧。

如果你收到请告诉我 谢谢

【讨论】:

嗨!谢谢字体的解释,现在我明白了,我提供了一个似乎可行的答案。你能看看它并告诉我是否需要改变任何东西。谢谢!【参考方案3】:

感谢@TemaniAfif 引导我朝着正确的方向前进,我想出了这个:

.r 
	width: 100%;
	height: 100%;
	min-width: 0px;
	max-width: 100%;


.container 
    display: flex;
    width: 600px;
<div class="container">
	<img src="https://lundbeckconsulting.no/Temp/illu1.jpg" class="r" />
	<img src="https://lundbeckconsulting.no/Temp/illu1.jpg" class="r" />
	<img src="https://lundbeckconsulting.no/Temp/illu1.jpg" class="r" />
	<img src="https://lundbeckconsulting.no/Temp/illu1.jpg" class="r" />
</div>

【讨论】:

以上是关于Firefox 和 Chrome 中 Flexbox 的不同实现的主要内容,如果未能解决你的问题,请参考以下文章

网站可在 Firefox 和 IE 中运行,但不适用于 Chrome

Firefox 和 Chrome 中 Flexbox 的不同实现

在 Chrome、Firefox 和 Safari 中强制标准/怪癖模式?

Firefox 和 Chrome 中的 CSS 行高不一样

CSS 动画在 chrome 中有效,但在 Firefox 和 Safari 中无效

如何在 Chrome 和 Firefox 中将按钮输入样式设置为相同?