How to make div height equal to width in CSS Grid
Asked Answered
H

4

18

I am using CSS Grid to layout a thumbnail gallery, no Javascript or any other responsive techniques. I would like to set the height of thumbnails to be as its width (1:1) square ratio.
Why? when the page loads I need the thumbnail div's to take space, because now if there is no Image inside the thumbnails div it doesn't take any space.

Here is a Live example: https://www.w3schools.com/code/tryit.asp?filename=FMCULIDQUOBX

Here is the Code:

.container {max-width: 900px;}
.gallery {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-gap: 15px;
}
.thumbnail {box-shadow: 0 4px 4px rgba(0,0,0,0.50);}
img {width: 100%; display: block;}

...............................

<div class="container">
  <div class="gallery">

    <div class="thumbnail">
      <a href="large-image.jpg">
        <img src="thumbnail-image.jpg">
      </a>
    </div>
    <div class="thumbnail">
      ...... same as above ......
    </div>
    <div class="thumbnail">
      ...... same as above ......
    </div>
    <div class="thumbnail">
      ...... same as above ......
    </div>

  </div>
</div>

The Code above divides the width (900px) into four fractions, and the 4 thumbnails are placed in 1 row. That's why I don't define any width.
If Images don't load, the thumbnail div wont even be visible.
In other words, if you disable images in browser, thumbnail div should take space in a square shape.
How to fix this? Thanks

Haymes answered 8/12, 2017 at 11:24 Comment(12)
There is no CSS-Grid method of creating squares based on fr units`.Behave
#1495907Behave
“when the page loads I need the thumbnail div's to take space” - then provide the actual image dimensions via width and height attributes in the HTML, so that the browser will know what the aspect ratio is upfront ... then it can calculate the correct height according to the width the image is display with before it has loaded the actual image.Ical
use max-* propertiesFenner
@Ical I couldn't do that, the layout will break when resizing browser window.Haymes
Why would it do that then?Ical
@Ical here is a live example: w3schools.com/code/tryit.asp?filename=FMCULIDQUOBXHaymes
Nothing breaks, as soon as you add height:auto for the images in your CSS.Ical
@Ical sorry, in previous comment i meant "without defining width". Adding height:auto doesn't make the div a square. Try adding that and disable Images in browser.Haymes
First of all, who does that? Those users are likely used to pages looking different, so that would not bother me too much. (And if it was just the images failing to load for some other reason, it would still work.) Secondly, with images disabled, a bunch of red squares is not going to help the user much in any case - so adding proper alt attributes is the least thing you should do here. But if the squares are that important, you can switch to the padding-bottom hack, too, if you like, that’s an alternative method to achieve image “placeholders” of the correct aspect ratio/dimensions.Ical
@Ical on live website its not Red and it does include alt attribute. I have tried with padding-bottom with no luck. Will try again with some modification to make it work.Haymes
worked with padding-bottom hack as @Ical suggested. w3schools.com/code/tryit.asp?filename=FMD1UJKTU72ZHaymes
B
16

The solution is to add an invisible square element (zero width and 100% bottom padding) to the grid, set equal height to all rows by grid-auto-rows: 1fr; and then reposition the invisible grid element as well as the first grid element to overlap.

So, your css file should look as the following:

.container {max-width: 900px;}

.gallery {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-gap: 15px;
}

.gallery::before {
    content: '';
    width: 0;
    padding-bottom: 100%;
    grid-row: 1 / 1;
    grid-column: 1 / 1;
}

.gallery > *:first-child{
    grid-row: 1 / 1;
    grid-column: 1 / 1;
}

.thumbnail {box-shadow: 0 4px 4px rgba(0,0,0,0.50);}

img {width: 100%; display: block;}
Benny answered 16/4, 2019 at 17:34 Comment(3)
I have no clue what you've done but it works.Custom
This is pure genius.Washboard
This is magic!!Jorge
T
16

the simplest solution is to add aspect-ratio: 1 to the css of the child divs (the cells)

your parent div css grid-template-columns: 1fr 1fr 1fr 1fr; creates 4 columns

Adding aspect-ratio: 1 to the css of the children of these columns forces each child to have the same height as width

.gallery {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
}
.thumbnail {
  aspect-ratio: 1
}


<div class="gallery">

     <div class="thumbnail">
            <img src="image1.jpeg">
     </div>

     <div class="thumbnail">
            <img src="image2.jpeg">
     </div>

     <div class="thumbnail">
            <img src="image3.jpeg">
     </div>

     <div class="thumbnail">
            <img src="image4.jpeg">
     </div>
</div>
Tympanum answered 9/3, 2023 at 23:30 Comment(3)
This is wonderful, not sure why it's not upvoted more!Rabble
This is a good solution, unfortunately iOS 14 and lower doesn't support aspect-ratio, so I had to go with a different solution.Cynthy
aspect-ratio, seems to fail the on safari.Christiano
D
13

I'm not sure how to do it with css grid but I know how to make .thumbnail maintain it's ratio.

I learnt this trick a while ago and I use it all the time since then.

.thumbnail{
   position: relative;
}
. thumbnail:before{
    content: ' ';
    display: block;
    width: 100%;
    padding-top: 100% \* Percentage value in padding derived from the width  *\
}
.thumbnail > img{
    position: absolute;
    top: 0px;
    left: 0px;
    bottom: 0px;
    right: 0px;
}
Drusi answered 24/5, 2018 at 13:55 Comment(0)
A
-3

The big advantage is that CSS grid by default applies a similar height to its children.

Option is to restructure the HTML and reduce markup (HTML). You can add height to the .gallery class to make it look more square.

.container {max-width: 900px; margin:0 auto;}
.gallery {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-gap: 15px;
}
.thumbnail {display:block; box-shadow: 0 4px 4px rgba(0,0,0,0.50);}
img {display:block; width:100%; height: auto;}
    <div class="container">
      <div class="gallery">
          <a class="thumbnail"  href="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
            <img src="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
          </a>
    
          <a class="thumbnail" href="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
            <img src="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
          </a>
    
          <a class="thumbnail"  href="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
            <img src="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
          </a>
    
          <a class="thumbnail"  href="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
            <img src="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
          </a>
        
        <a class="thumbnail"  href="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
            <img src="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
          </a>
    
          <a class="thumbnail" href="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
            <img src="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
          </a>
    
          <a class="thumbnail"  href="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
            <img src="https://static.pexels.com/photos/54278/pexels-photo-54278.jpeg">
          </a>
    
          <a class="thumbnail"  href="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
            <img src="https://static.pexels.com/photos/242276/pexels-photo-242276.jpeg">
          </a>
      </div>
    </div>

    
Alejandrinaalejandro answered 8/12, 2017 at 12:31 Comment(2)
This does not address the principal point of the question - " I would like to set the height of thumbnails to be as its width (1:1) square ratio."Behave
Here is a live example that you can experiment on: w3schools.com/code/tryit.asp?filename=FMCULIDQUOBXHaymes

© 2022 - 2024 — McMap. All rights reserved.