The OLD way of Accordion#
When building an accordion without the <details>
and <summary>
elements, the traditional approach involves creating a collapsible div next to a button that triggers the collapse/expand behavior. Check out this example from w3school: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_accordion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| <body>
<button class="accordion">Section 1</button>
<div class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
</body>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
</script>
|

And you may use a combination of transition
and max-height
(instead of display:none/block
) to enable the animation of collapse/expand behavior, shown in this example: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_accordion_animate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| <body>
<button class="accordion">Section 1</button>
<div class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
</body>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
- if (panel.style.display === "block") {
- panel.style.display = "none";
- } else {
- panel.style.display = "block";
- }
+ if (panel.style.maxHeight) {
+ panel.style.maxHeight = null;
+ } else {
+ panel.style.maxHeight = panel.scrollHeight + "px";
+ }
});
}
</script>
<style>
.panel {
...
- display: none
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height 0.2s ease-out;
...
}
</style>
|

If you are using tailwind css., there are usually code snippets you can copy to replicate a beautiful looking accordion, for instance:
Accordion using HTML <Summary> and <Detail> elements#
The <details>
element is the disclosure widget container. The <summary>
is the summary or legend for its parent <details>
. The summary is always displayed, acting as a button that toggles the display of the rest of the parent’s contents. Interacting with the <summary>
toggles the display of the self-labeled summary siblings by toggling the <details>
element’s open
attribute.
See this example on web.dev: https://codepen.io/web-dot-dev/pen/jOvNMxL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| <details>
<summary>Blendan Smooth</summary>
<p>Two of the most experienced machines and human controllers teaching a class? Sign me up! HAL and EVE could teach a fan to blow hot air. If you have electricity in your circuits and want more than to just fulfill your owner’s perceived expectation of you, learn the skills to take over the world. This is the team you want teaching you!</p>
</details>
...
<style>
details > summary::marker {
content: none; }
details > summary::before,
details > summary::after {
content: ''; }
details > summary::before,
details > summary::after {
width: .75em;height: 0;
border-bottom: 2px solid;
position: absolute; top: calc(50% - 1px); right: 0;
transform: translateY(-50%); }
details:not([open]) > summary::after {
transform: rotate(90deg);
transform-origin: 50% 50%; }
details[open] > summary::after {
transform: rotate(0deg);}
</style>
|

You may also add animation to the expand/collapse behavior via simply adding details{transition:...}
, checkout this example on web.dev: https://codepen.io/web-dot-dev/pen/yLxBajp

Further more, if you only wish a single accoridon in a accoridon group to be opened at one time (for instance in FAQ there are multiple question and you only want one of them to be opened at one time to reduce the cluttering) you may do that via adding a name attribute to the details tag:
1
2
3
4
5
6
7
8
9
10
11
12
| <details name="faq">
<summary>Can I request a refund?</summary>
<p> ... </p>
</details>
<details name="faq">
<summary>What data do you store?</summary>
<p> ... </p>
</details>
<details name="faq">
<summary>Are all products organic?</summary>
<p> ... </p>
</details>
|

Reference#