Search code examples
csscss-grid

Repeating grid layout with unknown amount of items


I'm working on a set of items and trying to position them with css's grid. My issue is that I'm placing them with nth-child so after the first 6 it just breaks. I'd like to be able to have an infinite amount of items and they'll all place themselves correctly. Basically the layout should repeat after the first 6 items.

.wrapper {
    display: grid;
    grid-template-columns: calc(50% - 4px) calc(50% - 4px);
    grid-template-rows: 120px 120px 120px 240px;
    gap: 8px;
    margin-left: 0;
    margin-right: 0;
}

.item {
  background: #bada55;
}

.item:nth-child(1) {
  grid-row-start: 1;
  grid-row-end: 3;
}
.item:nth-child(2) {
  grid-row-start: 1;
  grid-row-end: 2;

}
.item:nth-child(3) {
  grid-row-start: 2;
  grid-row-end: 3;
}

.item:nth-child(4) {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 3;
  grid-row-end: 4;
}
<div class="wrapper">
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
  <a class="item">
    Item
  </a>
</div>


Solution

  • Simply like below:

    .wrapper {
      display: grid;
      grid-template-columns: 1fr 1fr; /* fr instead of % */
      grid-auto-rows: 120px 120px 120px 240px; /* auto-rows instead of template-rows */
      grid-auto-flow: dense; /* fill all the space */
      gap: 8px;
    }
    
    .item {
      background: #bada55;
    }
    
    .item:nth-child(6n + 1) {
      grid-row: span 2; /* I will take 2 rows */
    }
    
    .item:nth-child(6n + 4) {
      grid-column: 1/-1; /* I will take all the columns  */
    }
    <div class="wrapper">
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
      <a class="item">
        Item
      </a>
    </div>