Search code examples
csscss-grid

Change the number of columns and rows in a grid as the number of items increase


I have to design a responsive grid.
The grid should change based on the number of items (instead of the size of the screen).

From 5 to 6 items should be 2x3,
from 7 to 9 items should be 3x3,
from 10 to 12 items should be 3x4,
from 13 to 16 items should be 4x4, and so on...

Is this something I can do using CSS Grid?

image

This is what I've tried:

<main>

  <figure>
    <img src="https://placekitten.com/600/400" alt="">
  </figure>

  <figure>
    <img src="https://placekitten.com/600/400" alt="">
  </figure>

  <figure>
    <img src="https://placekitten.com/600/400" alt="">
  </figure>

  <figure>
    <img src="https://placekitten.com/600/400" alt="">

  </figure>

  <figure>
    <img src="https://placekitten.com/600/400" alt="">
  </figure>

</main>

main {
  /* display: flex; */
  /* flex-wrap: wrap; */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  align-content: stretch;
  height: 100vh;
}
figure {
  margin: 0;
  /* flex-grow: 1; */
  /* flex-basis: 12rem; */
}
img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

Solution

  • Implicit columns creation can do this. You can consider nth-child()/nth-last-child() to create a new column when you reach a specific number of columns:

    .container {
      display: inline-grid;
      width: 100px;
      vertical-align: top;
      border: 1px solid;
    }
    .container > :nth-child(2) {
      grid-column: 2;
    }
    
    .container > :nth-last-child(n + 5) ~ :nth-child(3) { 
     grid-column: 3;
    }
    
    .container > :nth-last-child(n + 10) ~ :nth-child(4) { 
     grid-column: 4;
    }
    
    .container > :nth-last-child(n + 17) ~ :nth-child(5) { 
     grid-column: 5;
    }
    
    .container > * {
      border: 1px solid red;
      aspect-ratio: 1;
    }
    <div class="container">
    <div></div>
    </div>
    
    <div class="container">
    <div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
    
    <div class="container">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>