Search code examples
htmlcsscss-grid

How to make images respect grid row size constraints?


I'm trying to create a layout where a section with images takes up a certain fraction of the container's height. I tried to use grid-template-rows with fr units, but the image always prefers to stay in its original size and doesn't respect the row sizes of the parent grid. Also, I've tried to follow a few tips online and added object-fit: contain to let the image scale as needed and wrapped the image in a div, neither of which helped.

Simplified snippet:

.container {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  grid-template-rows: 3fr 2fr;
  height: 100vh;
}

img {
  object-fit: contain;
}

.hello {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
<div class="container">
  <div>
    <img
      src="http://via.placeholder.com/600x300"
    />
  </div>
  <div class="hello">
    <div>Hello</div>
    <div>Hello</div>
    <div>Hello</div>
    <div>Hello</div>
    <div>Hello</div>
    <div>Hello</div>
  </div>
</div>

What I'm expecting to see is two rows in a 3/2 ratio, instead, the image takes up as much space as it needs, not respecting the ratio at all.

Can I somehow make the grid to force the row sizes or the image to allow scaling?


Solution

  • The problem seems to be that the element containing the image is picking up a height from the content (ie the image).

    This snippet sets the width and height of the img element to 100% of its parent div but it positions it absolute so its actual dimensions have no effect on its parent.

    .container {
      display: grid;
      grid-template-columns: repeat(1, minmax(0, 1fr));
      grid-template-rows: 3fr 2fr;
      height: 100vh;
    }
    
    .container>div:first-child {
      position: relative;
    }
    
    img {
      object-fit: contain;
      position: absolute;
      height: 100%;
      width: 100%;
    }
    
    .hello {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    <div class="container">
      <div>
        <img src="http://via.placeholder.com/600x300" />
      </div>
      <div class="hello">
        <div>Hello</div>
        <div>Hello</div>
        <div>Hello</div>
        <div>Hello</div>
        <div>Hello</div>
        <div>Hello</div>
      </div>
    </div>