1

I want to place an image in a cell such that the size of the image is dictated by the size of the cell and not the other way around. I have tried doing it this way:

.app-container {
  width: 100vw;
  height: 100vh;
}

.info {
  display: grid;
  min-height: 0;
}

.image-box {
  display: grid;
  min-height: 0;
}

img {
  object-fit: contain;
  width: 100%;
  height: 100%;
  grid-row: 1;
  grid-column: 1;
}
<div class="app-container">
  <div class="info">
    <div class="image-box" style="grid-row-start: 1; grid-column-start: 1;">
      <img src="https://images.unsplash.com/photo-1482003297000-b7663a1673f1?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ">
    </div>
  </div>
</div>

But the image is always displayed in its original size and does not get scaled. What am I missing? Full example on JSFiddle here

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
user79074
  • 4,937
  • 5
  • 29
  • 57

1 Answers1

1

Images are ridiculously tricky in Grid and Flex layouts. I'm not sure if it's because Grid and Flex are new technologies and browsers haven't yet fully adapted them to the long-standing <img> tag. Or maybe it's something else. But bottom line: it sucks dealing with images in CSS3 technologies. You have to try different things, while testing each permutation in every major browser, because there's no guarantee of consistency.

One thing I've learned over the years that helps a lot is to never make an image a grid or flex item. In other words, never make the image the child of the container. Give the image it's own container, making that element the item. Once you make that move, a lot of things tend to fall into place.

Here is a revised version of your code (with no changes to the HTML):

Tested in Chrome, Firefox and Edge.

.image-box {
  height: 50vh;
  border: 2px solid red;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-areas: 
    " demo1 image demo2 "
    " demo1 image demo2 "
    " demo1 image demo2 ";
}

.image-box > div:first-child {
  grid-area: demo1;
  background-color: lightgreen;
}

.image-box > div:nth-child(2) {
  grid-area: image;
  min-width: 0;
}

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-box > div:last-child {
  grid-area: demo2;
  background-color: aqua;
}

.app-container {}
.info {}
<div class="app-container">
  <div class="info">
    <div class="image-box">
      <div>demo item 1</div>
      <div><img src="https://images.unsplash.com/photo-1482003297000-b7663a1673f1?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ">
      </div>
      <div>demo item 2</div>
    </div>
  </div>
</div>

jsFiddle demo

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • But in your example the image size is being specified explicitly. Is there a solution where it will always follow the proportions of the grid cell? If I remove image-box height and increase width of centre column again the image extends past the bottom – user79074 Apr 15 '20 at 22:05
  • That issue is illustrated here: https://jsfiddle.net/1vywkhoe/ – user79074 Apr 15 '20 at 22:08
  • I don't see the image extending past the bottom in your demo. The container is expanding to accommodate the image (as illustrated by the red border). Is setting a height on the container an option? https://jsfiddle.net/10x8qkun/ – Michael Benjamin Apr 17 '20 at 16:52