Accordions are commonly used when an interface has large groups of sectioned content, but all of the content doesn’t need to be available at the same time. In these instances the topics or headings are considered to be the necessary content of the screen. The content associated with the headings may only be of interest on an as-needed basis.

A good example of where an accordion interface could be appropriate, would be a frequently asked questions (F.A.Q.) page. In this instance, the questions would be considered headings to their answers. As the different answers are only useful to individuals that are interested in a particular question, those answers would be hidden by default, until a user wanted to expose them.

Looking at an example

Accordion functionality aside for a moment, a F.A.Q. page would typically use the following markup structure:

<h2> <!-- or h# depending on your document structure -->
  Question goes here
</h2>
<p>
  Answer to question goes here.
</p>
<!-- repeat -->

Adding accordion functionality on top of the above markup would necessitate the following:

1.The heading would need to act as a button to open and close the answer.

We don’t want to lose the semantics of the heading, but a heading alone isn’t a sufficient element to indicate that it serves as a toggle control. So what we’d want to do here, is inject a button within the heading, so that it can retain the heading semantics, while also exposing the fact it is an interactive element.

<h2> 
  <button>Question goes here</button>
</h2>

2. The state of button would need to be conveyed visually and to users of assistive technology.

The overall aesthetic of the project would dictate the requirements for how an accordion should be styled. Typically a visual indicator to convey the heading is more than just a block of text would be required. For example: a “down arrow” icon, an underline, or some other visual treatment to make the text appear interactive.

Additionally styles for hover, focus, and expanded states would be necessary (assuming that “collapsed” is the default style state). Providing these visual indicators will help draw attention to the functionality of the trigger. A straight forward design that is commonly accepted to indicate an element is “actionable” will ensure that those who may not be very tech or design savvy will readily understand the functionality.

For users of assistive technologies (such as screen readers), ARIA attributes like aria-expanded would be placed on the button to expose the current state of its associated content. Additional attributes may be necessary if an accordion group requires that a panel must be open at all times.

<h2> 
  <button aria-expanded="true/false">Question goes here</button>
</h2>

3. The answer should only be available to users when in the “expanded” state.

A problem I’ve seen in some implementations of accordions (and other components that require content to be hidden) is the misconception that the “hidden” content should be moved off-screen, but should not be completely hidden from assistive technologies.

In other words, while an accordion’s trigger may indicate that it’s closed, its associated content would still be parsed by a screen reader. This sort of situation creates a misalignment in the user experience for those who are using a screen reader, those who are sighted, and those who may fall somewhere in between (e.g. sighted keyboard users).

Essentially, not hiding content appropriately, in regards to accordions, is like saying:

  • “Sighted users, you don’t have to parse content you don’t want to.”
  • “Screen reader users, and sighted keyboard users, you likely do have to interact with content that you may not want to.” E.g. hidden focusable links would still be accessible. And standard methods for navigating content on a page, with assistive technologies, would still parse the hidden text.
  • “Oh, and also, sighted keyboard users, you can’t even see the content you’re interacting with.” (unless additional JavaScript was written to auto-open accordion panels if content within them was focused. But this would be fixing a symptom and not the underlying issue.)

Creating UX parity is imperative in ensuring you’re providing the best, and most consistent user experience to everyone. So if content is meant to be hidden, make sure it’s hidden to everyone.

<h2> 
  <button aria-expanded="false">Question goes here</button>
</h2>
<div hidden> <!-- not expanded, so hide the content! -->
  <p>My answer goes here!</p>
</div>

ARIA Accordion Script

I’ve updated my accordion JavaScript from being based on a previous version of the ARIA Authoring Practices, to be more in line with the current recommendation. It is now written in ES5, instead of jQuery.

You can find the source for the script on GitHub, where I document additional functionality and options that are available. Please read through the documentation (it’s not too long) for additional context on how the accordion script functions, and the role that ARIA plays in the user experience.

Or go right to a demonstration of the accordion script in action.

As an interesting aside, for those of you who may be wondering how to allow for (some of) the functionality of an accordion without the need for JavaScript, check out Adrian Roselli’s CSS-only accordion CodePen.

Finally, take a look through the WAI-ARIA Authoring Practices 1.1 accordion documentation.