Skip to content

Instantly share code, notes, and snippets.

@ihorduchenko
Created March 24, 2022 12:33
Show Gist options
  • Save ihorduchenko/587c86faaaacd59a8d13c2652b67b587 to your computer and use it in GitHub Desktop.
Save ihorduchenko/587c86faaaacd59a8d13c2652b67b587 to your computer and use it in GitHub Desktop.
CSS + JS accordions using max-height transition
<div class="acordian">
<div class="acordian-trigger">
Accordion trigger
</div>
<div class="acordian-content">
Accordion content inner
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis reiciendis placeat velit sit adipisci beatae laudantium sapiente provident recusandae corporis.
</div>
</div>
<style>
.acordian-content {
overflow: hidden;
transition: 0.5s max-height;
will-change: max-height;
}
.acordian.is-hidden .acordian-content {
position: absolute;
opacity: 0;
visibility: hidden;
}
</style>
<script>
class Accordion {
constructor($el) {
this.$el = $el;
this.$title = this.$el.querySelector('.acordian-trigger');
this.$content = this.$el.querySelector('.acordian-content');
this.isOpen = false;
this.height = 0;
this.events();
this.close();
}
events() {
this.$title.addEventListener('click', this.handleClick.bind(this));
this.$content.addEventListener('transitionend', this.handleTransition.bind(this));
}
handleClick() {
this.height = this.$content.scrollHeight;
if (this.isOpen) {
this.close();
} else {
this.open();
}
}
close() {
this.isOpen = false;
this.$el.classList.remove('is-open');
this.$content.style.maxHeight = `${this.height}px`;
setTimeout(() => {
this.$content.style.maxHeight = `${0}px`;
}, 1);
}
open() {
this.isOpen = true;
this.$el.classList.add('is-open');
this.$el.classList.remove('is-hidden');
this.$content.style.maxHeight = `${0}px`;
setTimeout(() => {
this.$content.style.maxHeight = `${this.height}px`;
}, 1);
}
handleTransition() {
if (!this.isOpen) {
this.$el.classList.add('is-hidden');
}
this.$content.style.maxHeight = '';
}
}
const accordians = document.querySelectorAll('.acordian');
if (accordians) {
accordians.forEach((el) => {
new Accordion(el);
});
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment