10

I have a grid in which I position images but they doen't fill the entire space they are given.

I hope the image below illustrates the problem good enough. As we can see the top image as well as the right one don't fill the rows they are assigned to. What causes this and how can I fix it?

Code is like that:

 <section class="wrapper">
   <div class="one">
     <img class="img" src="images/lorem/ipsum.jpg" alt="">
   </div>

   <div class="two">
     <img class="img" src="images/lorem/ipsum2.jpg" alt="">
   </div>

   <div class="three">
     <img class="img" src="images/lorem/ipsum3.jpg" alt="">
   </div>
 </section>

 .wrapper {
   display: grid;
   grid-template-columns: repeat(8, 1fr);
   grid-auto-rows: minmax(150px, auto);
   grid-gap: 20px;
   height: 100vh;
 }

.one {
  grid-column: 2 / 7;
  grid-row: 1 / 3;
}

.two {
  grid-column: 2 / 5;
  grid-row: 3 / 4;
} 

.three {
  grid-column: 5 / 7;
  grid-row: 3 / 4;
}

.img {
  width: 100%;
}

enter image description here

How can I fix this?

Unknown User
  • 505
  • 1
  • 7
  • 19
  • 1
    You should include the HTML so we can reproduce the problem. These posts may help: [**here**](https://stackoverflow.com/q/46616289/3597276) and [**here**](https://stackoverflow.com/a/47285891/3597276). – Michael Benjamin May 26 '18 at 12:21
  • maybe the minmax set at 150px is too much ? can you clarify with your HTML structure and image sizes to demonstrate your issue ... maybe it also have to do with HTML ? – G-Cyrillus May 26 '18 at 13:53
  • @G-Cyr I did add the HTML. The fix Yan suggested kinda solves the problem of the gaps but now when I resize the images get cut – Unknown User May 26 '18 at 14:14
  • for image you can take a look at https://css-tricks.com/almanac/properties/o/object-fit/ (similar effect than background-size) . The thing is that for the image to fill entire cell grid you will have to cut off part of it or stretch them. if their size size doesn't fit at first. Do you want to stretch them ? – G-Cyrillus May 26 '18 at 14:24
  • No I don't want to stretch them. They should keep their aspect ratio. Thanks for the link! – Unknown User May 26 '18 at 14:53

8 Answers8

15

I had a similar problem to this before , the simple solution is to set the height or width to 100% for the img elements to fill their container. Then to set the object fit property to cover for better cropping. You don't even need div containers for your images. Like this:

The grid container will take care of the positioning of the cells.

img{
width: 100%;
height: 100%;
object-fit: cover;
}
MosDev
  • 151
  • 1
  • 3
9

add one div to wrap your image, then set image style to .img { max-width: 100%; height: auto }

Liang Lyon
  • 174
  • 1
  • 5
5

This is normal because images are preserving their aspect ratio.

A good way to solve this common problem is to set the image as a CSS-background parameter in a div in your grid instead of an <img> tag in html, such as background: url('http://link-to-your-image/image.jpg') and use background-size: cover; on the same element.

This way, the picture will fill out all the space that is attributed to it.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Yan
  • 353
  • 1
  • 4
  • 13
  • Ok, well thanks that helps. I'm surprised. Is this the only way you can solve this issue for images you want in your CSS Grid? – Unknown User May 26 '18 at 13:21
  • 'fit-content: cover' is similar to the background image stuff but for img objects – AGrush Jun 08 '19 at 12:26
0

Try background-size: 100% 100% and background-size: cover or fit

kissan
  • 11
  • 1
0

This worked for me using React with inline styles:

<div 
    style = {{
        gridArea: "image",
        backgroundImage: `url(${imageFromImports})`,
        backgroundSize: "contain",
        backgroundRepeat: "no-repeat",
        backgroundPosition: "center",
    }}
/>
lami
  • 1,410
  • 12
  • 16
0

I finally discovered the rules to dynamically resizing images within a css grid. They are:

  1. Every nested grid element of the parent grid must have min-height: 0 set, including the img tag itself
  2. The img tag must also define max-width: 100%
  3. The immediate grid parents of the img tags must also have min-width: 0 set for the align- and justify- properties to work correctly

Here is sample code that will work:

// parent
<div css={{
    display: "grid",
    gridTemplateRows: "max-content 1fr",
    height: "50vh",
    maxHeight: "50vh",
}}>
    <header></header>

    <div css={{
      display: "grid",
      gridTemplateRows: "3fr 2fr",
      minHeight: 0,
    }}>
        <div css={{
          display: "grid",
          minHeight: 0,
          minWidth: 0,
        }}>
            <img
                css={{
                  maxHeight: "100%",
                  minHeight: 0,
                  borderRadius: 10,
                }}
            />
        </div>

        <div css={{
          display: "grid",
          minHeight: 0,
        }}>
            {imgs.map(img => 
                <div css={{
                  display: "grid",
                  minHeight: 0,
                  minWidth: 0
                }}>
                    <img
                        css={{
                          maxHeight: "100%",
                          minHeight: 0,
                          borderRadius: 10,
                        }}
                    />
                    <p>...</p>
                </div>
            }
        </div>
    </div>
</div>
55 Cancri
  • 1,075
  • 11
  • 23
0

adding min-height: 0; to my img tag solved the issue for me fully. Thank you very much for your post! Best, I

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 27 '23 at 06:48
0

Browser preserving aspect ratio does appear to be the reason why this is not as straightforward as you might think.

I was able to get the image to fill a grid cell by nesting the IMG in a parent DIV and then simply applying the following to the class on the image:

I prefer this over using a background for accessibility reasons.

.image {
  aspect-ratio: 2/1;
  border-radius: var(--default-border-radius);
  object-fit: cover;
  height: 100%;
  max-width: 100%;
}

Here's a demo:

:root {
  --grid-gutter: 25px;
  --grid-max-width: 1440px;
}

.image {
  aspect-ratio: 2/1;
  object-fit: cover;
  height: 100%;
  max-width: 100%;
}

.grid {
  display: grid;
  grid-column-gap: var(--grid-gutter);
  grid-template-columns: repeat(12, minmax(0, 1fr));
  margin-left: auto;
  margin-right: auto;
  max-width: var(--grid-max-width);
  padding-bottom: 0;
  padding-left: var(--grid-gutter);
  padding-right: var(--grid-gutter);
  padding-top: 0;
  row-gap: var(--grid-gutter);
}

.large-span-4 {
  grid-column: span 4;
}

.large-span-8 {
  grid-column: span 8;
}
<aside class="four-eight grid">
  <div class="large-span-4">
    <h4 class="title">Lorem ipsum is placeholder text</h4>
    <p class="copy">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
      dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
    <div class="">
      <a href="#" class="link">Learn About It</a>
    </div>
  </div>
  <div class="large-span-8">
    <img class="image" src="https://placehold.co/600x600" />
  </div>
</aside>
xyeres
  • 155
  • 2
  • 7