Search code examples
htmlcsscss-grid

Is a CSS grid with automatically laid out items that are "staggered" on rows and columns possible?


I'm trying to determine if it's possible for a CSS grid to automatically lay out items that stagger each other on both the column and row level.

It's kinda hard to describe exactly what I'm wanting, so here is an example of how such a grid would look, given the items were in the right order (so not necessarily in the order I have them in the HTML currently):

.grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  grid-auto-rows: 100px;
  column-gap: 20px;
  row-gap: 20px;
  justify-content: center;
}

.grid div{
  background-color: gray;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 30px;
  color: white;
}

.grid-item-1{
  grid-row-start: 1;
  grid-row-end: 2;
  grid-column-start: 1;
  grid-column-end: 3;
}

.grid-item-2{
  grid-row-start: 1;
  grid-row-end: 3;
  grid-column-start: 3;
  grid-column-end: 4;
}

.grid-item-3{
  grid-row-start: 2;
  grid-row-end: 3;
  grid-column-start: 2;
  grid-column-end: 3;
}

.grid-item-4{
  grid-row-start: 2;
  grid-row-end: 4;
  grid-column-start: 1;
  grid-column-end: 2;
}

.grid-item-5{
  grid-row-start: 3;
  grid-row-end: 4;
  grid-column-start: 2;
  grid-column-end: 4;
}
<div class="grid">
  <div class="grid-item-1">1</div>
  <div class="grid-item-2">2</div>
  <div class="grid-item-3">3</div>
  <div class="grid-item-4">4</div>
  <div class="grid-item-5">5</div>
</div>

I would like to be able to give the items pixel heights and widths and let the grid automatically lay them out in this arrangement, without me having the grid area of each item hard coded.

I've searched for solutions all over, but to no avail. I just want to know if it's possible, or if such a layout is only possible with hard coded grid areas for each item.


Solution

  • All what you need is to set up either the number of rows or columns

    .grid{
      display: grid;
      grid-template-columns: repeat(3, 100px); /* only 3 here */
      grid-auto-rows: 100px;
      grid-auto-flow:dense; /* don't forget this */
      column-gap: 20px;
      row-gap: 20px;
      justify-content: center;
    }
    
    .grid div{
      background-color: gray;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 30px;
      color: white;
    }
    
    .grid-item-1,
    .grid-item-5{
      grid-row: span 2;
    }
    
    .grid-item-2,
    .grid-item-4{
      grid-column: span 2;
    }
    <div class="grid">
      <div class="grid-item-1">1</div>
      <div class="grid-item-2">2</div>
      <div class="grid-item-3">3</div>
      <div class="grid-item-4">4</div>
      <div class="grid-item-5">5</div>
    </div>