Search code examples
csscss-grid

How to alternate grid pattern for unknown number of items


I want to create a repeating grid. Three items per row.

First row: item one spans 2 cols and 2 rows. Followed by item two and item three spanning 1 col and 1 row.

Second row would be inverse: item one and item two span 1 col and 1 row. item 3 spans 2 cols and 2 rows.

See image below for what I'm trying to do. I wanting this for an infinite amount of rows and items.

enter image description here

.container {
  width: 100%;
  margin: 0 auto;
  max-width: 80%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}

h2 {
  font-size: 16px;
  font-family: sans-serif;
  font-weight: normal;
}

.item {
  background: pink;
}

.item:nth-child(3n+1) {
  grid-column: auto /span 2;
  grid-row: auto /span 2;

}

.item:nth-child(3n+2),
.item:nth-child(3n+3) {
  /* grid-area: 1 / 3 / 2 / 4; */
  border: 1px solid red;
  grid-column: auto /span 1;
  grid-row: auto /span 1;
}

.container.two .item:nth-child(3n+1) {
    border: 5px solid yellow;
    grid-area: 1 / 1 / 2 / 2;
  }
  
.container.two .item:nth-child(3n+2) {
    border: 5px solid orange;
    grid-area: 2 / 1 / 3 / 2;

  }

.container.two .item:nth-child(3n+3) {
    border: 5px solid red;
    grid-area: 1 / 2 / 3 / 4;
  }


img {
  max-width: 100%;
}
<h2>
I have this using "grid-column" and "grid-row"...
</h2>
<div class="container">
  <div class="item">
    First
  </div>
  <div class="item">
    Second
  </div>
  <div class="item">
    Third
  </div>
</div>

<hr />

<h2>
I want to alternate that, but I only understand how to with "grid-area"...
</h2>
<div class="container two">
  <div class="item">
    First
  </div>
  <div class="item">
    Second
  </div>
  <div class="item">
    Third
  </div>
</div>
<hr/>
<h2>
But I want to have an unlimited amount of items alternate those patterns...
</h2>
<div class="container">
  <div class="item">
    First
  </div>
  <div class="item">
    Second
  </div>
  <div class="item">
    Third
  </div>
  <div class="item">
    First
  </div>
  <div class="item">
    Second
  </div>
  <div class="item">
    Third
  </div>
  <div class="item">
    First
  </div>
  <div class="item">
    Second
  </div>
  <div class="item">
    Third
  </div>
  <div class="item">
    First
  </div>
  <div class="item">
    Second
  </div>
  <div class="item">
    Third
  </div>
  <div class="item">
    First
  </div>
  <div class="item">
    Second
  </div>
  <div class="item">
    Third
  </div>
</div>


Solution

  • You can do it like below:

    .container {
      display:grid;
      grid-template-columns:repeat(3,1fr); /* 3 columns */
      grid-auto-flow:dense; /* make sur to fill all the area */
      grid-auto-rows:50px; /* height of one row */
      grid-gap:5px;
    }
    .container * {
      background:red;
    }
    /* the pattern repeat each 6 elements */
    .container :nth-child(6n + 1),
    .container :nth-child(6n + 6){
      grid-area:span 2/span 2; /* 1 and 6 take 2 rows and 2 columns */
    }
    
    .container :nth-child(6n + 5){
      grid-column:1; /* 5 at first column */
    }
    <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>