On my website, I have a reviews section similar to the one on the official Tailwind CSS website.
In my reviews section, I have a button you can press to show more or show less reviews.
The show more feature works fine, but when I press the button again to show less reviews, the page moves a lot.
I'm not sure how to stop the page from moving when the "show less" part happens.
To reproduce bug
https://tailwindcss.com has a working solution on their website (it's the second section) but I haven’t been able to figure out how they prevent the page from jumping when the reviews are collapsed.
Here is a minimal code example
const toggleButton = document.getElementById("toggle-button")
const grid = document.getElementById("grid")
let isCollapsed = false
toggleButton.addEventListener("click", () => {
isCollapsed = !isCollapsed
if (isCollapsed) {
grid.classList.add("collapsed")
} else {
grid.classList.remove("collapsed")
}
})
body {
padding: 72px;
}
.filler-content {
background: seashell;
width: 100%;
height: 1600px;
}
#grid {
background: black;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.grid-item {
background: lightblue;
padding: 80px;
}
#toggle-button {
background: orange;
padding: 16px;
position: fixed;
bottom: 4px;
}
.collapsed {
max-height: 20rem;
overflow: hidden;
}
<div class="filler-content">this is filler content... scroll down</div>
<section>
<p>scroll down more until you see next message</p>
<div id="grid">
<div class="grid-item">review1</div>
<div class="grid-item">review2</div>
<div class="grid-item">review3</div>
<div class="grid-item">review4</div>
<div class="grid-item">review5</div>
<div class="grid-item">review6</div>
<div class="grid-item">review7</div>
<div class="grid-item">review8</div>
<div class="grid-item">review9</div>
<div class="grid-item">review10</div>
<div class="grid-item">review11</div>
<div class="grid-item">review12</div>
<div class="grid-item">review13</div>
<div class="grid-item">review14</div>
<div class="grid-item">review15</div>
<div class="grid-item">review16</div>
<div class="grid-item">review17</div>
</div>
<div id="toggle-button">Show less/Show more reviews</div>
</section>
<div class="filler-content">this is filler content.. click the orange button when it is below this sentence</div>
The tailwind website does not work how you think it does. In that:
they do not "stop the page from moving"
instead
they do "move you back to the start of the section".
The user has already scrolled("moved") the page. When you collapse your grid, the scroll position will remain where the user last put it. This is not only expected, but crucial to creating webpage dynamics function across renders.
In order to achieve the effect you mention, you need to scroll the page back to the start of your grid section. You can achieve this by changing your event listener as follows:
toggleButton.addEventListener("click", () => {
isCollapsed = !isCollapsed;
if (isCollapsed) {
grid.classList.add("collapsed");
grid.scrollIntoView();
} else {
grid.classList.remove("collapsed");
}
})