Transition does not work with height: auto. So I need to calculate and set the block's dynamic height with JavaScript to make the transition property work. This is an example of my code:
<div class="accordion__item">
<div class="accordion__icon">
<div class="accordion__content">
</div>
</div>
</div>
const accItems = document.querySelectorAll('.accordion__item');
accItems.forEach((item) => {
const icon = item.querySelector('.accordion__icon');
const content = item.querySelector('.accordion__content');
item.addEventListener("click", () => {
if (item.classList.contains('open')) {
item.classList.remove('open');
icon.classList.remove('open');
content.classList.remove('open');
} else {
const accOpen = document.querySelectorAll('.open');
accOpen.forEach((open) => {
open.classList.remove('open');
});
item.classList.add('open');
icon.classList.add('open');
content.classList.add('open');
}
});
});
How can I do this?
It's not ideal but there is not much we can do with transitioning height.
For a workaround, give your open class a max-height property that is larger than your expect the largest open element to get. From there you can transition the max-height property.
There are also some optimizations you can make to your event listener callback. I don't believe you need to add open to all the elements in the accordion, just the item itself.
Try something like this:
const accItems = document.querySelectorAll('.accordion__item');
accItems.forEach((item) => {
item.addEventListener("click", () => {
const openItems = document.querySelectorAll(".open")
openItems.forEach(open => open.classList.toggle("open"))
item.classList.toggle("open")
}
});
Then in your css:
.open {
max-height: 200px
}
.accordion__item {
max-height: 0;
transition: max-height 200ms ease;
}