My goal is to create a responsive grid with an unknown amount of items, that keep their aspect ratio at 16 : 9. Right now it looks like this:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, 160px);
grid-template-rows: 1fr;
grid-gap: 20px;
}
.item {
height: 90px;
background: grey;
}
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
The problem is, that the items won't scale with the screen size, resulting in a margin at the right site. But when making the grid adapt to the screen size with e.g.: grid-template-columns: repeat(auto-fit, minmax(160p, 1fr))
and removing the height: 90px;
, the aspect ratio doesn't persist.
Maybe there is a better solution without css grid? (Maybe using javascript)
In the CSS for the <div>, add a percentage value for padding-bottom and set the position to relative, this will maintain the aspect ratio of the container. The value of the padding determines the aspect ratio. ie 56.25% = 16:9.
It helped me to find the following solution: Instead of setting grid-gap, set grid-column-gap and grid-row-gap separately, with grid-row-gap equal to grid-column-gap / (1 - grid-column-gap). Set padding-bottom of the container equal to grid-column-gap.
Grid:CSS Grid Layout, is a two-dimensional grid-based layout system with rows and columns, making it easier to design web pages without having to use floats and positioning.
Fr is a fractional unit and 1fr is for 1 part of the available space.
You could take advantage of the fact that padding in percentages is based on width.
This CSS-tricks article explains the idea quite well:
...if you had an element that is 500px wide, and padding-top of 100%, the padding-top would be 500px.
Isn't that a perfect square, 500px × 500px? Yes, it is! An aspect ratio!
If we force the height of the element to zero (height: 0;) and don't have any borders. Then padding will be the only part of the box model affecting the height, and we'll have our square.
Now imagine instead of 100% top padding, we used 56.25%. That happens to be a perfect 16:9 ratio! (9 / 16 = 0.5625).
So in order for the columns to maintain aspect ratio:
Set the column widths as you suggested:
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr))
Add a pseudo element to the items to maintain the 16:9 aspect ratio:
.item:before {
content: "";
display: block;
height: 0;
width: 0;
padding-bottom: calc(9/16 * 100%);
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
grid-template-rows: 1fr;
grid-gap: 20px;
}
.item {
background: grey;
display: flex;
justify-content: center;
}
.item:before {
content: "";
display: block;
height: 0;
width: 0;
padding-bottom: calc(9/16 * 100%);
}
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
We can now use aspect-ratio
CSS4 property (Can I Use ?) to manage easily aspect ratio without padding and pseudo-element tricks. Combined with object-fit
we obtain very interesting rendering.
Here, photos of various ratios I need to render in 16/9 :
section {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* Play with min-value */
}
img {
background-color: gainsboro; /* To visualize empty space */
aspect-ratio: 16/9;
/*
"contain" to see full original image with eventual empty space
"cover" to fill empty space with truncating
"fill" to stretch
*/
object-fit: contain;
width: 100%;
}
<section>
<img src="https://placeimg.com/640/360/architecture">
<img src="https://placeimg.com/640/360/tech">
<img src="https://placeimg.com/360/360/animals">
<img src="https://placeimg.com/640/360/people">
<img src="https://placeimg.com/420/180/architecture">
<img src="https://placeimg.com/640/360/animals">
<img src="https://placeimg.com/640/360/nature">
</section>
Playground : https://codepen.io/JCH77/pen/JjbajYZ
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With