Skip to content

Accordion

How to make an accordion element with CSS only and no JavaScript?

Accordion

A accordion element is great for organizing content in a collapsible and expandable manner, allowing users to quickly find the information they need without being overwhelmed by too much content at once.
This page shows two code examples, one simple non-animated accordion and one that is animated. Both can be made without JavaScript.

Example

That was a great click! 💪

The Most Simple Accordion

The easiest way to build an accordion is by using the details and summary element. This allows us to build a very simple and functional accordion instantly without any CSS or JavaScript.

.html
<details>
<summary>Section 1</summary>
<p>This is the content of Section 1. You can put any HTML elements here.</p>
</details>

Control over it’s styling and behaviour is limited though. By using input and label instead we can build an accordion over which we have much more control as shown below.

Simple Accordion

.html
<div class="accordion">
<input type="checkbox" name="collapse-checkbox" id="firstid" />
<label for="firstid">
<span>This is a nice text or title.</span>
<span class="caret-icon">&gt;</span>
</label>
<div class="collapsable">
<p>This text can be hidden.</p>
</div>
</div>
.css
input[name="collapse-checkbox"] {
display: none;
}
label {
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
}
.collapsable {
height: 0px;
overflow: hidden;
}
input[name="collapse-checkbox"]:checked ~ .collapsable {
height: auto;
}
input[name="collapse-checkbox"]:checked ~ label .caret-icon {
transform: rotate(90deg);
}
span {
margin-right: 1rem;
}

Animated Accordion

To make the accordion animated we need add a transform, but there’s a problem. Transition does not work on the height property when we go from 0 to auto. So what can we do?

We start by making the container a grid element and defining grid-template-rows as 0fr. Then we define grid-template-rows as 1fr on checked and transition this instead. We move over the overflow: hidden to the child element. Finally we add the transition property to the collapsable element and icon, that’s it.

.css
input[name="collapse-checkbox"] {
display: none;
}
label {
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
}
.caret-icon {
transition: transform 200ms;
}
.collapsable {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 250ms;
}
.collapsable > * {
overflow: hidden;
}
input[name="collapse-checkbox"]:checked ~ .collapsable {
grid-template-rows: 1fr;
}
input[name="collapse-checkbox"]:checked ~ label .caret-icon {
transform: rotate(90deg);
}
span {
margin-right: 1rem;
}

Now you should have all the skills to build your own accordion element and style it to your liking. To make it look exactly like the example above replace the text caret with a svg image and then swap the two lines, placing the icon before the text. Add a bit of margin-right to the svg icon and it’s done.

Further Links: