Skip to content

Instantly share code, notes, and snippets.

@sayhicoelho
Last active May 22, 2023 08:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sayhicoelho/f74f6073c9c3357fae5e4770886c3e01 to your computer and use it in GitHub Desktop.
Save sayhicoelho/f74f6073c9c3357fae5e4770886c3e01 to your computer and use it in GitHub Desktop.
Pure JS accordion based on Bootstrap Collapse.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#btn-accordion-1 {
margin-top: 10px;
margin-bottom: 10px;
}
.accordion {
transition: height 150ms ease;
}
.accordion:not(.show):not(.collapsing) {
display: none;
}
.accordion.collapsing {
height: 0;
overflow: hidden;
}
.accordion .content {
padding: 22px;
}
.container {
width: 600px;
margin-left: auto;
margin-right: auto;
}
.tooltip {
position: absolute;
background: black;
color: white;
padding: 8px 10px;
max-width: 200px;
text-align: center;
visibility: visible;
opacity: 1;
transition: visibility 150ms ease, opacity 150ms ease;
}
.tooltip:not(.show) {
visibility: hidden;
opacity: 0;
}
</style>
</head>
<body>
<div class="container">
<button id="btn-accordion-1" data-toggle="accordion" data-target="#accordion-1">
Accordion 1
</button>
<div id="accordion-1" class="accordion" style="background-color: red;">
<div class="content">
<h2>Accordion 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sed odio obcaecati quaerat ducimus sint nemo. Porro reiciendis autem nulla at minus exercitationem sequi cupiditate, perspiciatis quibusdam labore ut velit obcaecati!</p>
<button id="btn-accordion-2" data-toggle="accordion" data-target="#accordion-2">
Accordion 2
</button>
<div id="accordion-2" class="accordion" style="background-color: yellow;">
<div class="content">
<h4>Accordion 2</h4>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ducimus repellat hic voluptatibus consequatur. Magnam, harum exercitationem aperiam unde vero omnis architecto asperiores quidem natus magni impedit dolores tenetur quas nisi.</p>
<button data-toggle="tooltip" data-target="#tooltip">
Hover me
</button>
<div id="tooltip" class="tooltip">
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', e => {
const accordions = document.querySelectorAll('.accordion')
const accordionBtns = document.querySelectorAll('[data-toggle="accordion"]')
const tooltipsBtns = document.querySelectorAll('[data-toggle="tooltip"]')
tooltipsBtns.forEach(btn => {
btn.addEventListener('mouseenter', e => {
const { target } = e.currentTarget.dataset
const tooltip = document.querySelector(target)
const top = btn.offsetTop + btn.scrollHeight + 11
const left = btn.offsetLeft
tooltip.classList.add('show')
tooltip.style.setProperty('top', top + 'px')
tooltip.style.setProperty('left', left + 'px')
})
btn.addEventListener('mouseleave', e => {
const { target } = e.currentTarget.dataset
const tooltip = document.querySelector(target)
tooltip.classList.remove('show')
})
})
accordionBtns.forEach(btn => {
btn.addEventListener('click', e => {
const { target } = e.currentTarget.dataset
const accordion = document.querySelector(target)
const isActive = accordion.classList.contains('show')
const isCollapsing = accordion.classList.contains('collapsing')
if (isCollapsing) return
if (!isActive) {
accordion.classList.add('collapsing')
accordion.style.setProperty('height', accordion.scrollHeight + 'px')
setTimeout(() => {
accordion.classList.add('show')
accordion.style.removeProperty('height')
accordion.classList.remove('collapsing')
}, 150)
} else {
accordion.style.setProperty('height', accordion.scrollHeight + 'px')
setTimeout(() => {
accordion.classList.add('collapsing')
accordion.classList.remove('show')
accordion.style.removeProperty('height')
}, 5);
setTimeout(() => {
accordion.classList.remove('show')
accordion.classList.remove('collapsing')
}, 150)
}
})
})
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment