The code below shows the intended behavior when I resize the window in Chrome 60, and in Firefox 55 (but not in iOS Safari 10.3; that is most likely another question why it misbehaves in Safari).
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
border: 0;
background-color: lightgrey;
}
.container {
box-sizing: border-box;
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: repeat(3, calc((60vh - 12px)/3));
/*grid-template-rows: 1fr 1fr 1fr;*/
/*grid-template-rows: auto auto auto;*/
height: 60vh;
border: 3px solid yellow;
padding: 3px;
/*grid-gap: 20px;*/ /* <-- would also mess things up */
}
.tile {
}
img {
box-sizing: border-box;
display: block;
object-fit: contain;
width: 100%;
height: 100%;
margin: 0;
border: 0;
padding: 3px;
}
<!-- The image is 200 x 100 px: a green and a blue square next to each other. -->
<div class="container">
<div class="tile">
<img src="https://i.stack.imgur.com/qbpIG.png" alt="." />
</div>
<div class="tile">
<img src="https://i.stack.imgur.com/qbpIG.png" alt="." />
</div>
<div class="tile">
<img src="https://i.stack.imgur.com/qbpIG.png" alt="." />
</div>
<div class="tile">
<img src="https://i.stack.imgur.com/qbpIG.png" alt="." />
</div>
<div class="tile">
<img src="https://i.stack.imgur.com/qbpIG.png" alt="." />
</div>
<div class="tile">
<img src="https://i.stack.imgur.com/qbpIG.png" alt="." />
</div>
</div>
It is important that the aspect ratio of the images (2:1)
is preserved. I would have expected either:
grid-template-rows: 1fr 1fr 1fr;
or:
grid-template-rows: auto auto auto;
makes the images fit within the rows of the grid, but neither of them does. With:
grid-template-rows: repeat(3, calc((60vh - 12px)/3));
I get the desired behavior. How can I avoid working out the math myself? In other words, what should I do so that grid-template-rows: 1fr 1fr 1fr;
(or something similar) works?
It is already difficult to work out the height of the container element in CSS on the real page. The goal is to solve it with CSS grid layout; no JavaScript, and no background image hacks.
Update: I originally excluded the background image hack for two reasons.
I thought (due to some misunderstandings) that the background image url must be in the CSS file, but this is not the case: I can use inline styles and have it in the HTML.
It felt hackish. After having seen how complicated and messy it gets with nested flex containers nested inside a grid container just to make it work on Safari, I simply resorted to the background image hack as it is significantly cleaner and works in all browsers tested (Chrome, Firefox, Safari).
In the end, it is not the accepted answer that helped to solve my problem.