CSS Grid Row Height Safari Bug
Asked Answered
G

4

29

I've made a grid template with rows of 1fr 1fr 1fr. In the middle row, there are a list of inline images.

In Chrome and Firefox, the images respect the height of the grid row and adapt properly. However, in Safari 10.1.2 and Safari TP 31, there appears to be a combination of the images overflowing the row and not scaling the image widths appropriately.

Perhaps I'm doing something wrong? Or is this a Safari bug? And if so, is there a workaround?

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/

Glanti answered 26/6, 2017 at 23:23 Comment(0)
S
48

Short Answer

The problem is that Safari is not recognizing the height: 100% on the img elements.


Explanation

This is not a Safari bug. It's just a different interpretation of the spec.

When dealing with percentage heights, some browsers (like Safari) adhere to the traditional interpretation of the spec, which requires a defined height on the parent.

10.5 Content height: the height property

<percentage>

Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the used height is calculated as if auto was specified.

In other words, a percentage height on an in-flow element will be recognized only when the parent has a defined height.

Some browsers, such as Chrome and Firefox, have moved past this interpretation and now accept flex and grid heights as an adequate parent reference for a child with a percentage height.

But Safari is stuck in the past. This doesn't mean it's wrong, invalid or a bug.

The last substantive update to the CSS height definition was in 1998 (CSS2). With so many new CSS properties and technologies since that time, the definition has become obsolete, unclear and woefully incomplete. Until the definition is updated for modern use, browser rendering variations can be expected.


Solution

Since Safari doesn't recognize the height: 100% on the img elements, and you can't specify a height on the parent (#thumbnailContainer) because that height is defined by grid-template-rows: 1fr on the top-level container, you can try using flexbox.

By making #thumbnailContainer a flex container, you can define the size of the images (flex items) using flex properties.

#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


More information

Sievert answered 27/6, 2017 at 5:57 Comment(2)
Absolutely genius and very appreciated. Thank you for explaining the issue so thoroughly and making the flex box work around!Glanti
this worked for me, thank you very much. I always have problems with div heights being different in some scenarios on IOS chrome/safari, but totally fine with pc and android. I don't understand why IOS is always different and why we need these work arounds..Calender
M
9

Don't ask me why, but wrapping the grid parent with a simple div solved my problem.

This article (https://newbedev.com/why-is-css-grid-row-height-different-in-safari) mentions:

Put display:grid on the div surrounding your grid container.

My problem was solved just by wrapping the grid container with a div. Just wanted to mention another solution. I hope someone can add an explanation for what is happening here.

Mesial answered 13/11, 2021 at 0:10 Comment(4)
I can confirm this works for me as well! It would be interesting to know how or why this works though...Mushro
This hasn't worked for me unfortunately.Tantalus
I was losing it, thanks for sharing your solutionAilment
I'm honestly shocked this worked, but very glad it did!Dance
D
0

Anyone with similar issues, if you use GRID, don't set the first level child to 100% height. Safari will not take GRID (parent of that component) as a relative 100% height.

In my case, Safari made the GRID content (with 100% height) overflow the GRID.

Deste answered 26/1, 2024 at 17:35 Comment(0)
N
0

I have ran into similar situation, in which the child-item text content expands vertically way outside the container on Safari. The child item is set with display:flex; and justify-content: center whereas the parent container is set with display:grid; and flex-direction:row;.

Applying the grid-template-rows: max-content; on the parent grid container resolves this issue.

Note that this may not be completely related to the question above, but sharing this as a potential solve for similar situation.

Narcotism answered 3/7, 2024 at 17:25 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.