How to Build an HTML Accordion (No CSS or JavaScript!)

What if I told you there was a native HTML element that allows you toggle the display of content without the use of any CSS or JavaScript?
Allow me to introduce one of the most revolutionary HTML elements since the marquee: the <details>
element.
The <details>
element is the answer to every needlessly complicated component you’ve ever had to create and manipulate just to toggle content on a page. With this element, we have a fully functional display toggle component right off the bat - and it's semantic too!
HTML Accordion Demo
Here it is in all its straightforward glory. Go ahead, click away:
Don’t worry, we won’t actually stop there. With some simple CSS it is possible to make this HTML accordion even better:
At this point, you might be wondering “If this element is so great, why isn’t it more widely used?” The short answer: cross-browser compatibility.
In its early stages, the <details>
element wasn’t supported by all browsers so it required using polyfills, which kinda defeated the point of using a native HTML element. Luckily for us the web has evolved considerably and with a cross-browser compatible value of 97.1% (at the time of writing this article), we can confidently use this element for all our toggle-related needs.



Without wasting any further time, let’s get right to it.
1. Using the <details> and <summary> element
The <details>
element works in the same way an accordion-item does: it has a header and content which is made visible by clicking the header. The header for the <details>
element is the <summary>
element. Here’s what the standard syntax looks like:
1 |
<details>
|
2 |
<summary>Accordion Header goes here</summary> |
3 |
<div>
|
4 |
Accordion content goes here |
5 |
</div>
|
6 |
</details>
|
Any element wrapped in the <details>
element below the <summary>
element is automatically hidden and toggled by clicking the <summary>
element.
In this tutorial, we’ll be recreating the JavaScript accordion component we created in a previous tutorial:
Here’s what the layout for this accordion looks like using the <details>
and <summary>
elements:
1 |
<details class="accordion-item"> |
2 |
<summary class="accordion-trigger"> |
3 |
<span class="accordion-title"> |
4 |
How does an accordion work? |
5 |
</span>
|
6 |
<span class="accordion-icon" aria-hidden="true"> |
7 |
+
|
8 |
</span>
|
9 |
|
10 |
</summary>
|
11 |
<div class="accordion-content"> |
12 |
<p>It toggles collapsible content based on user interaction.</p> |
13 |
</div>
|
14 |
</details>
|
15 |
|
16 |
<details class="accordion-item"> |
17 |
<summary class="accordion-trigger"> |
18 |
<span class="accordion-title"> |
19 |
Why should I use an accordion? |
20 |
</span>
|
21 |
<span class="accordion-icon" aria-hidden="true"> |
22 |
+
|
23 |
</span>
|
24 |
|
25 |
</summary>
|
26 |
<div class="accordion-content"> |
27 |
<p>It helps improves user exerience by providing condensed information in an easy-to-read manner.</p> |
28 |
</div>
|
29 |
</details>
|
30 |
|
31 |
<details class="accordion-item"> |
32 |
<summary class="accordion-trigger"> |
33 |
<span class="accordion-title"> |
34 |
Is an accordion a type of animal? |
35 |
</span>
|
36 |
<span class="accordion-icon" aria-hidden="true"> |
37 |
+
|
38 |
</span>
|
39 |
|
40 |
</summary>
|
41 |
<div class="accordion-content"> |
42 |
<p>No, you're thinking of an armadillo.</p> |
43 |
</div>
|
44 |
</details>
|
Here’s what it looks like:



And that’s all folks! We have our fully functional accordion component set up. Since we have our functionality set up, we can now play around with our styling.
2. Add Some CSS
Let’s recreate the layout from our JavaScript accordion and also override the default <details>
styling.
To remove the triangle in the summary element, we’ll simply override the display property on the accordion-trigger
class which is assigned to <summary>
. We’ll also include the remaining styling to get our desired layout:
1 |
.accordion-trigger { |
2 |
width: 100%; |
3 |
display: flex; |
4 |
background-color: rgb(250, 250, 250); |
5 |
color: rgb(0, 0, 0); |
6 |
padding: 24px; |
7 |
font-size: 18px; |
8 |
font-weight: 500; |
9 |
font-family: 'Roboto', sans-serif; |
10 |
text-align: left; |
11 |
border: none; |
12 |
gap: 16px; |
13 |
justify-content: space-between; |
14 |
cursor: pointer; |
15 |
}
|
We can also take advantage of the details open
attribute to style our accordion item when it’s expanded. In this demo, we rotate the accordion item from a cross to an “x” when it’s expanded.
1 |
.accordion-icon { |
2 |
transition: transform 0.5s; |
3 |
}
|
4 |
|
5 |
.accordion-item[open] .accordion-icon { |
6 |
transform: rotate(45deg); |
7 |
}
|
Conclusion
And that’s all we need. Here’s our final demo:
Now go forth and enjoy all the time you’ve saved from not writing custom accordion scripts.