Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to Achieve Smooth Expansion and Prevent Grid Row Gaps with Hidden Elements in CSS

I’m working on a web layout where I have a section containing visible and hidden content. I’ve implemented a button to expand the hidden content smoothly using a transition effect. However, I’m facing two main issues:

While the expandable functionality works, the transition effect isn’t as smooth as I’d like it to be. I’ve applied a CSS transition to change the grid-template-rows property, but it’s not providing the desired smoothness. How can I achieve a smoother transition effect when expanding the hidden content?

Grid Row-Gap Reservation: I’m using a grid layout for the hidden content, and even when elements are hidden, the row-gap seems to be reserving extra space for them, causing a visual gap in the layout. I want to prevent this row-gap reservation for hidden elements. How can I modify my CSS to ensure that the row-gap is only applied to visible elements and not to hidden ones?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here’s a simplified version of my HTML, CSS, and JavaScript code:
https://codepen.io/korneliuszburian/pen/LYaqyvN

document.addEventListener("DOMContentLoaded", () => {
  const button = document.querySelector(".btn__expand");
  let currentIndex = 0;
  let hiddenGroups = document.querySelectorAll(".cards--hidden");

  button.addEventListener("click", function() {
    if (currentIndex < hiddenGroups.length) {
      hiddenGroups[currentIndex].classList.remove("cards--hidden");
      hiddenGroups[currentIndex].classList.add("cards--active");
      currentIndex++;
    }

    if (currentIndex >= hiddenGroups.length) {
      button.style.display = "none";
    }
  });
});
body {
  background-color: #f0f0f0;
  font-family: Arial, sans-serif;
  padding: 20px;
}

.visible,
.cards--hidden {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #fff;
  border: 1px solid #000;
  box-shadow: 5px 5px 0px #000;
}

.wrapper {
  border: 2px solid #000;
  padding: 10px;
  min-height: 0;
  overflow: hidden;
}

.items {
  margin-bottom: 10px;
  padding: 10px;
  background-color: #e0e0e0;
  border: 1px solid #000;
}

.item__title h2 {
  font-size: 20px;
  margin: 0 0 5px 0;
  color: #000;
}

.item__title p {
  font-size: 16px;
  margin: 0;
  color: #333;
}

.cards--hidden {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 300ms ease-in-out;
  overflow: hidden;
}

.cards--active {
  grid-template-rows: 1fr;
}

.btn__expand {
  cursor: pointer;
}
<section>
  <div class="visible">
    <div class="wrapper">
      <div class="items">
        <div class="item__title">
          <h2>Visible Item 1 Title</h2>
          <p>Description for Visible Item 1</p>
        </div>
      </div>
      <div class="items">
        <h2>Visible Item 2 Title</h2>
        <p>Description for Visible Item 2</p>
      </div>
      <div class="items">
        <h2>Visible Item 3 Title</h2>
        <p>Description for Visible Item 3</p>
      </div>
    </div>
  </div>
  <div class="cards cards--hidden">
    <div class="wrapper">
      <div class="items">
        <div class="item__title">
          <h2>Hidden Item 1 Title</h2>
          <p>Description for Hidden Item 1</p>
        </div>
      </div>
      <div class="items">
        <h2>Hidden Item 2 Title</h2>
        <p>Description for Hidden Item 2</p>
      </div>
      <div class="items">
        <h2>Hidden Item 3 Title</h2>
        <p>Description for Hidden Item 3</p>
      </div>
    </div>
  </div>
  <div class="cards cards--hidden">
    <div class="wrapper">
      <div class="items">
        <div class="item__title">
          <h2>Hidden Item 1 Title</h2>
          <p>Description for Hidden Item 1</p>
        </div>
      </div>
      <div class="items">
        <h2>Hidden Item 2 Title</h2>
        <p>Description for Hidden Item 2</p>
      </div>
      <div class="items">
        <h2>Hidden Item 3 Title</h2>
        <p>Description for Hidden Item 3</p>
      </div>
    </div>
  </div>
  <div class="btn__expand">
    <span class="btn__label">Expand all data</span>
  </div>
</section>

>Solution :

You only added display: grid to .cards--hidden, while it changes to .cards--visible, the container becomes block, so grid-template-rows: 1fr losts its effect and its transition is also lost.

You could move these rules to the general selector .cards, to allow the transition work as intended

.cards {
  display: grid;
  transition: grid-template-rows 300ms ease-in-out;
}
document.addEventListener("DOMContentLoaded", () => {
  const button = document.querySelector(".btn__expand");
  let currentIndex = 0;
  let hiddenGroups = document.querySelectorAll(".cards--hidden");

  button.addEventListener("click", function() {
    if (currentIndex < hiddenGroups.length) {
      hiddenGroups[currentIndex].classList.remove("cards--hidden");
      hiddenGroups[currentIndex].classList.add("cards--active");
      currentIndex++;
    }

    if (currentIndex >= hiddenGroups.length) {
      button.style.display = "none";
    }
  });
});
body {
  background-color: #f0f0f0;
  font-family: Arial, sans-serif;
  padding: 20px;
}

.visible,
.cards--hidden {
  padding: 15px;
  background-color: #fff;
  border: 1px solid #000;
  box-shadow: 5px 5px 0px #000;
}

.wrapper {
  border: 2px solid #000;
  padding: 10px;
  min-height: 0;
  overflow: hidden;
}

.items {
  margin-bottom: 10px;
  padding: 10px;
  background-color: #e0e0e0;
  border: 1px solid #000;
}

.item__title h2 {
  font-size: 20px;
  margin: 0 0 5px 0;
  color: #000;
}

.item__title p {
  font-size: 16px;
  margin: 0;
  color: #333;
}

.cards {
  display: grid;
  transition: grid-template-rows 300ms ease-in-out;
}

.cards--hidden {
  grid-template-rows: 0fr;
  overflow: hidden;
}

.btn__expand {
  cursor: pointer;
  margin-top: 20px;
}

/* hide the wrapper content */
.cards--hidden .wrapper {
  padding: 0;
  border: none;
}

/* add gap to visible items */
.visible, .cards--active {
  grid-template-rows: 1fr;
  margin-bottom: 20px;
}
<section>
  <div class="visible">
    <div class="wrapper">
      <div class="items">
        <div class="item__title">
          <h2>Visible Item 1 Title</h2>
          <p>Description for Visible Item 1</p>
        </div>
      </div>
      <div class="items">
        <h2>Visible Item 2 Title</h2>
        <p>Description for Visible Item 2</p>
      </div>
      <div class="items">
        <h2>Visible Item 3 Title</h2>
        <p>Description for Visible Item 3</p>
      </div>
    </div>
  </div>
  <div class="cards cards--hidden">
    <div class="wrapper">
      <div class="items">
        <div class="item__title">
          <h2>Hidden Item 1 Title</h2>
          <p>Description for Hidden Item 1</p>
        </div>
      </div>
      <div class="items">
        <h2>Hidden Item 2 Title</h2>
        <p>Description for Hidden Item 2</p>
      </div>
      <div class="items">
        <h2>Hidden Item 3 Title</h2>
        <p>Description for Hidden Item 3</p>
      </div>
    </div>
  </div>
  <div class="cards cards--hidden">
    <div class="wrapper">
      <div class="items">
        <div class="item__title">
          <h2>Hidden Item 1 Title</h2>
          <p>Description for Hidden Item 1</p>
        </div>
      </div>
      <div class="items">
        <h2>Hidden Item 2 Title</h2>
        <p>Description for Hidden Item 2</p>
      </div>
      <div class="items">
        <h2>Hidden Item 3 Title</h2>
        <p>Description for Hidden Item 3</p>
      </div>
    </div>
  </div>
  <div class="btn__expand">
    <span class="btn__label">Expand all data</span>
  </div>
</section>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading