CSS Grid 行高 Safari Bug

28

我用 1fr 1fr 1fr 的行做了一个网格模板。中间一行有一系列内联图片。

在 Chrome 和 Firefox 中,这些图片会尊重网格行的高度并适当适应。然而,在 Safari 10.1.2 和 Safari TP 31 中,这些图片似乎既溢出了行,又没有适当地缩放图像宽度。

也许我做错了什么?还是这是 Safari 的 bug?如果是,那么有没有解决方法?

Safari 10.1

enter image description here

Safari TP

enter image description here

Chrome 60

enter image description here

#grid {
  height: 100vh;
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
}

#thumbnailContainer {
  position: inherit;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
}

img {
  display: inline;
  height: 100%;
  width: auto;
}

header,
footer {
  background-color: dodgerblue;
}
<div id="grid">
  <header>Header</header>
  <div id="thumbnailContainer">
    <img src="https://c2.staticflickr.com/8/7591/16903911106_b7ced9d758.jpg">
    <img src="https://c1.staticflickr.com/9/8740/16927517701_810fcb2a7c.jpg">
    <img src="https://c2.staticflickr.com/8/7637/16902583636_15138a68f0.jpg">
    <img src="https://c2.staticflickr.com/8/7614/16927530091_6755845b13.jpg">
    <img src="https://c1.staticflickr.com/9/8700/16741099010_d0ecd9df1f.jpg">
    <img src="https://c1.staticflickr.com/9/8745/16927567841_74fd20d01d.jpg">
  </div>
  <footer>Footer</footer>
</div>

https://jsfiddle.net/fqkjhh6m/1/

2个回答

44

简短回答

问题在于Safari无法识别img元素上的height: 100%


解释

这并不是Safari的Bug,而只是规范不同的解释。

在处理百分比高度时,一些浏览器(如Safari)遵循传统的规范解释,要求父元素有明确定义的高度。

10.5 内容高度: height 属性

<percentage>

指定一个百分比高度,百分比相对于生成框包含块的高度计算。如果未显式指定包含块的高度(即依赖内容高度),并且该元素没有绝对定位,则使用的高度将被计算为如果指定了auto

换句话说,仅当父元素具有定义高度时,才会识别流动元素上的百分比高度。

一些浏览器,如Chrome和Firefox,已经超越这种解释,并认为flex和grid高度是具有百分比高度子元素的足够父级参考。

但Safari仍停留在过去。这并不意味着它是错误的、无效的或者是一个bug。

CSS height 定义的最后一次实质性更新是在1998年(CSS2)。由于自那时以来出现了许多新的CSS属性和技术,该定义已经过时、不清楚且非常不完整。在该定义为现代使用进行更新之前,可以预期浏览器渲染差异。


解决方案

由于Safari无法识别img元素上的height: 100%,而且您无法在父级(#thumbnailContainer)上指定高度,因为该高度由顶层容器上的grid-template-rows: 1fr定义,您可以尝试使用flexbox。

通过使#thumbnailContainer成为flex容器,您可以使用flex属性定义图像(弹性项目)的大小。

#grid {
  height: 100vh;
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
}
#thumbnailContainer {
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  min-width: 0;
  min-height: 0;
}
img {
  flex: 0 0 35%;
  min-width: 0;
  object-fit: cover;
}
header, footer {
  background-color: dodgerblue;
}
<div id="grid">
  <header>Header</header>
  <div id="thumbnailContainer">
    <img src="https://c2.staticflickr.com/8/7591/16903911106_b7ced9d758.jpg">
    <img src="https://c1.staticflickr.com/9/8740/16927517701_810fcb2a7c.jpg">
    <img src="https://c2.staticflickr.com/8/7637/16902583636_15138a68f0.jpg">
    <img src="https://c2.staticflickr.com/8/7614/16927530091_6755845b13.jpg">
    <img src="https://c1.staticflickr.com/9/8700/16741099010_d0ecd9df1f.jpg">
    <img src="https://c1.staticflickr.com/9/8745/16927567841_74fd20d01d.jpg">
  </div>
  <footer>Footer</footer>
</div>

jsFiddle


更多信息


3
非常聪明,十分感谢。感谢您详细解释问题并使弹性盒子正常工作! - D. Walsh

7
不要问我为什么,但是用一个简单的div包装网格父容器解决了我的问题。
这篇文章 (https://newbedev.com/why-is-css-grid-row-height-different-in-safari) 提到:

在包围网格容器的div上放置display:grid

我的问题只需用一个div包装网格容器就解决了。我希望有人能解释一下这里发生了什么。

3
我也可以确认这对我有效!不过,了解这是如何或为什么有效会很有趣... - Alberto Fernández
这对我来说不幸没有起作用。 - Badger
1
我快要崩溃了,谢谢你分享你的解决方案。 - undefined
1
我真的很震惊这个方法居然奏效了,但我非常高兴它确实起作用了! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接