Search code examples
javascripthtmlcsscss-grid

change grid layout on click event


Is it possible to change a grid layout on a click event? I have a grid display of three rows and I want the grid to be changed to three columns when an item in the row is clicked.

.gridcontainer {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  justify-content: center;
}

.gridcontainer {
  display: grid;
  grid-template-columns: 1fr 4fr 1fr;
  justify-content: center;
}
<div class="gridcontainer">
  <div class="item">Item</div>
  <div class="item">Item</div>
  <div class="item">Item</div>
  <div class="item">Item</div>
  <div class="item">Item</div>
  <div class="item">Item</div>
</div>

On a click event on any of the items, I want the grid display to change from three rows to three columns.


Solution

  • Make two separate classes:

    .row {
      grid-template-rows: 1fr 1fr 1fr;
    }
    
    .col {
      grid-template-columns: 1fr 4fr 1fr;
    }
    

    Toggle each class on .gridcontainer on each click. Details commented in demo.

    // Reference the .gridcontainer
    var grid = document.querySelector('.gridcontainer');
    
    // Register click event to grid callback rowCol runs on click
    grid.onclick = rowCol;
    
    /* 
    Callback function rowCol() passes the Event Object...
    if the clicked element (e.target) .matches() class .item...
    get the clicked element's (ie .item) .closest() element .gridcontainer and 
    add/remove class .col or .row
    */
    function rowCol(e) {
      if (e.target.matches('.item')) {
        e.target.closest('.gridcontainer').classList.toggle('row');
        e.target.closest('.gridcontainer').classList.toggle('col');
      }
      return false;
    }
    .gridcontainer {
      display: grid;
      justify-content: center;
    }
    
    .row {
      grid-template-rows: 1fr 1fr 1fr;
    }
    
    .col {
      grid-template-columns: 1fr 4fr 1fr;
    }
    <div class="gridcontainer row">
      <div class="item">Item</div>
      <div class="item">Item</div>
      <div class="item">Item</div>
      <div class="item">Item</div>
      <div class="item">Item</div>
      <div class="item">Item</div>
    </div>