Back to the Basics: Accordions

Creating accordions from scratch

Mate Vegh
Wunderman ThompsonBudapest
4 min readFeb 1, 2018

--

In this article I’m going to share my experiences about creating accordions from scratch. I’m going to talk about the difficulties I’ve encountered and how I resolved them.

But first, let’s recap why we use accordions and in which situations they can enhance user experience. Accordions can be very helpful when a page has a lot of content. They let the user scan through the headings and effectively open their content without redirecting them to a new page.

So let’s start with the first step in the creation of a custom accordion.

Let’s assume the following HTML structure as a starting point:

The HTML structure for our accordion

With the following CSS (no decoration styles included):

Part of the CSS for our accordion

And the following JavaScript function, which is responsible for opening the accordion:

Part of the JavaScript for our accordion

This solution works well as long as we don’t want to use transition, and the height of the content is not greater than the set max-height. But let’s say we want to incorporate a nice expanding animation. In that case, this solution does not meet our expectations, as the transition will be lousy. It’s lousy not just because of the transition, but because it assumes a maximum available space for content to be put in, and on responsive sites we shouldn’t restrict anything like that.

At this point we know that we no longer want to limit the height using CSS, but we want to calculate it with JavaScript instead:

Part of the CSS for our accordion

But how do we get the initial height of an element which has a height set to zero? Well, this was my first attempt:

Part of the JavaScript for our accordion

It works, but I knew there had to be a better way. With a bit of digging around I found the Element.scrollHeight property.

“The Element.scrollHeight read-only property is a measurement of the height of an element’s content, including content not visible on the screen due to overflow.”

So, with this new knowledge in mind, let’s modify our JavaScript:

Part of the JavaScript for our accordion

So much better! But wait, there’s a trick: What if we wanted to add some padding to our accordion body? We’d have to deal with that, too, because it prevents the accordion body from having zero height.

We could solve that as follows:

Part of the CSS and JavaScript for our accordion

But I think there is a better way. Let’s wrap the accordion body in a container div:

The HTML structure for our accordion

Now we can use the accordion container to control the height and set padding safely for the accordion body:

Part of the CSS for our accordion

We can also use either Element.offsetHeight or Element.scrollHeight for getting the height of the accordion body:

Part of the JavaScript for our accordion

So, there you have it. This is my current solution for basic accordions. Let’s look at some working examples I’ve made recently:

This one uses the “checkbox hack” technique, so we can therefore choose between single and multiselect by setting the input elements’ type to either radio or checkbox. As far as I know, the only limitation on this technique is that every single input element needs a unique id in order to make it work, but in some cases this can also turn to our advantage, as well.

If setting unique id-s is an issue, here’s a full JavaScript version I’ve made:

This technique does not require setting id or attributes, but the HTML structure is more limited, so in case we need to change it, we’d need to modify the JavaScript code to reflect the changes in the HTML structure.

Of course, these could be improved with some nice-to-have features (like initial state, or bulk setting single or multiselect for accordion groups), but in this article I just wanted to point out the core concept I used.

As a final word

I’d like to encourage everyone to take a step back and consider building up your own solution sometimes, instead of using some ready-made code without thinking.

“But why should we do something that is already done by someone else?”

  1. It’s not about replicating the already-existing stuff, it’s about improving and optimizing it just for our project’s requirements, not more, not less.
  2. Ready-made solutions can be very useful and sometimes they completely fit our project’s requirements. But most of the time when we use third-party stuff, we will likely need to make adjustments to make it fit in the design, or make compromises because of its limitations. Sometimes it’s just easier to create our own solution.
  3. If not for any other reason, do it for learning: there’s a good chance that as we are experimenting, we’ll learn something new, just as I did.

Don’t misunderstand, I’m not saying that we should create everything from scratch, but minor things, like accordions, can make all the difference. Thanks for reading this article, I hope you enjoyed it!

--

--