2

I have a 2 x 2 CSS grid. Each grid item briefly describes a service (small business website) and each grid item has a button to learn more about said service. When a user clicks one of the four buttons to learn more, I would like that grid item to expand to take up the entire 2x2 grid (this I have working) and for the other 3 grid items to disappear (this I am having trouble with). Here is an example: https://jsfiddle.net/L7fatdmh/ , note that only the first grid item has JS applied to it at the moment.

firstButton = document.getElementById("firstButton");
firstButton.onclick = function() {
  squaresGrid = document.getElementsByClassName("grid-squares");
  g1 = document.getElementById("g1");
  console.log(g1)
  g1.style.gridColumn = "1/3";
  g1.style.gridRow = "1/3";
}
.grid-squares {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 300px;
}
<div class="grid-squares">
  <div class="grid_item" id="g1">
    <h2>Service One</h2>
    <p>
      lorem impsum
    </p>
    <button id="firstButton">Learn More</button>
  </div>
  <div class="grid_item">
    <h2>Service Two</h2>
    <p>
      lorem impsum
    </p>
    <button>Learn More</button>
  </div>
  <div class="grid_item">
    <h2>Service Three</h2>
    <p>
      lorem impsum
    </p>
    <button>Learn More</button>
  </div>
  <div class="grid_item">
    <h2>Service Four</h2>
    <p>
      lorem impsum
    </p>
    <button>Learn More</button>
  </div>
</div>

As you can see in the jsFiddle example, the grid item does expand to fill the proper space, but all of the other grid items are still visible underneath. How can I hide these? Is initially hiding all grid-items and then displaying a specific item based on it's id (i.e g1 in the first grid item) the best option?

djvg
  • 11,722
  • 5
  • 72
  • 103

2 Answers2

0

You can select the elements that are not your event target and hide them.

Using your fiddle, if we add

gOther = document.querySelectorAll(".grid_item:not(#g1)");

for (g of gOther) {
 g.style.display = "none";
}

It would work, but for a real world scenario you would need to make this a little bit more complete and look for elements that are not your target.

Renan Souza
  • 905
  • 9
  • 25
0

One solution would be to modify the values for grid-template-rows and grid-template-columns to expand and/or collapse specific rows and columns whenever a button is clicked.

For a small grid with fixed number of rows and columns, this can be done using dedicated classes, as in the example below. For a large grid, or one that is created dynamically, you can modify the inline style for the grid element instead, using JavaScript.

To hide the content from the collapsed cells, we can use background-color and overflow: hidden.

A quick-and-dirty modification of the OP's example can be found below. Click the buttons to toggle between the collapsed and expanded states.

const grid = document.querySelector('.grid');
grid.addEventListener('click', toggleExpansion);

function toggleExpansion(event) {
  if (event.target.tagName === 'BUTTON') {
    event.currentTarget.classList.toggle(`expand-${event.target.id}`);
  }
}
.grid {
  display: grid;
  grid-template-rows: 150px 150px;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
}

.grid-item {
  background-color: lightsteelblue;
  overflow: hidden;
}

.expand-1 {
  grid-template-rows: 300px 0px;
  grid-template-columns: 100% 0%;
  gap: 0px;
}

.expand-2 {
  grid-template-rows: 300px 0px;
  grid-template-columns: 0% 100%;
  gap: 0px;
}

.expand-3 {
  grid-template-rows: 0px 300px;
  grid-template-columns: 100% 0%;
  gap: 0px;
}

.expand-4 {
  grid-template-rows: 0px 300px;
  grid-template-columns: 0% 100%;
  gap: 0px;
}
<div class="grid">
  <div class="grid-item">
    <h2>Service One</h2>
    <p>
      lorem impsum
    </p>
    <button id="1">Learn More</button>
  </div>
  <div class="grid-item">
    <h2>Service Two</h2>
    <p>
      lorem impsum
    </p>
    <button id="2">Learn More</button>
  </div>
  <div class="grid-item">
    <h2>Service Three</h2>
    <p>
      lorem impsum
    </p>
    <button id="3">Learn More</button>
  </div>
  <div class="grid-item">
    <h2>Service Four</h2>
    <p>
      lorem impsum
    </p>
    <button id="4">Learn More</button>
  </div>
</div>

Note the gap is only used here to clarify what is happening.

Note that the changes in grid-template-rows and grid-template-columns can be animated, by specifying a transition in the .grid class. This does pose some restrictions on units etc. as mentioned here:

simple list of length, percentage, or calc, provided the only differences are in the values of the length, percentage, or calc components in the list

Another alternative would be to use dynamic columns as described e.g. here.

djvg
  • 11,722
  • 5
  • 72
  • 103