Jam
Jam

Reputation: 63

CSS grid auto-fill columns with static minmax values

I want to display a variable number of images of equal height and size in a symmetrical grid. Using CSS grid and auto-fill and minmax I was hoping to be able to define a minimum and a maximum pixel width for my tracks so I could prevent the image from being scaled too small while fitting as many images on a single row as the users viewport allows. Given the following markup:

    <div class="gallery">
      <a href="">
        <img src="https://via.placeholder.com/300/300" alt="">
      </a>
      <a href="">
        <img src="https://via.placeholder.com/300/300" alt="">
      </a>
      <a href="">
        <img src="https://via.placeholder.com/300/300" alt="">
      </a>
      <a href="">
        <img src="https://via.placeholder.com/300/300" alt="">
      </a>
      <a href="">
        <img src="https://via.placeholder.com/300/300" alt="">
      </a>
      <a href="">
        <img src="https://via.placeholder.com/300/300" alt="">
      </a>
      <a href="">
        <img src="https://via.placeholder.com/300/300" alt="">
      </a>
    </div>

Where each image has an intrinsic dimensions of 300 x 300px I would of expected the following CSS to have achieved that:

img {
  max-width: 100%;
}
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 300px));
  grid-gap: 1rem;
}

However what I'm seeing is that the tracks are not scaling between 300 and 210px, instead the track wraps as soon as the 300px cannot be accommodated.

However I can achieve the desired result using max-content instead.

img {
  max-width: 100%;
}
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, max-content));
  grid-gap: 1rem;
}

But max-content will be the maximum width the image will occupy and this should be 300px so I don't understand why using a static value of 300px doesn't have the same affect.

Upvotes: 6

Views: 1320

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 372149

Tricky situation, because minmax tends to default to the max value, and it appears that's what the browser considers when triggering a wrap.

I think the best approach currently available would be to use max-content on the container (as you have), and then control the max-width of the image at the grid item level.

Also, switch from auto-fill to auto-fit, so that empty tracks collapse and there is space for max-width to work.

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
  grid-gap: 1rem;
}

a {
  max-width: 300px;
}

img {
  width: 100%;
}
<div class="gallery">
  <a href="">
    <img src="https://via.placeholder.com/300/300" alt="">
  </a>
  <a href="">
    <img src="https://via.placeholder.com/300/300" alt="">
  </a>
  <a href="">
    <img src="https://via.placeholder.com/300/300" alt="">
  </a>
  <a href="">
    <img src="https://via.placeholder.com/300/300" alt="">
  </a>
  <a href="">
    <img src="https://via.placeholder.com/300/300" alt="">
  </a>
  <a href="">
    <img src="https://via.placeholder.com/300/300" alt="">
  </a>
  <a href="">
    <img src="https://via.placeholder.com/300/300" alt="">
  </a>
</div>

jsFiddle demo

Upvotes: 4

Related Questions