An accordion component is a collection of expandable panels associated with a common outer container. Panels consist of a header and an associated content region or panel. The primary use of an Accordion is to present multiple sections of content on a single page without scrolling, where all of the sections are peers in the application or object hierarchy. The general look is similar to a tree where each root tree node is an expandable accordion header. The user navigates and makes the contents of each panel visible (or not) by interacting with the Accordion Header.
—
- Container—the containing element wrapping all accordion items.
- Trigger—the accordion item label and control that expands and collapses its corresponding Target.
- Target—the containing element wrapping the content associated with the Trigger.
No JavaScript
<x class="js-accordion">
<x class="js-accordion-trigger">[...]</x>
<x class="js-accordion-target">[...]</x>
</x>
With JavaScript
<x class="js-accordion" role="tablist" aria-multiselectable="true">
<x class="js-accordion-trigger [is-expanded]" id="[accordion-trigger-x]" aria-controls="[id-of-'js-accordion-trigger']" aria-selected="[true/false]" aria-expanded="[true/false]" tabindex="[-1/0]" role="tab">[...]</x>
<x class="js-accordion-target [is-expanded]" id="[accordion-target-x]" aria-labelledby="[id-of-'js-accordion-target']" aria-hidden="[true/false]" role="tabpanel">[...]</x>
</x>
[is-expanded]
is the state hook that is toggled according to the expanded or collapsed state of the accordion item, by default and when collapsed the hook isn't applied, when expanded appendis-expanded
to both the Trigger and Target elements.- ARIA attributes having the values 'true' or 'false' are toggled according to the expanded or collapsed state of the accordion item:
- Trigger:
aria-selected
andaria-expanded
by default and when collapsed is 'false', when expanded is 'true'. - Target:
aria-hidden
by default and when collapsed is 'true', when expanded is 'false'.
- Trigger:
- The
id
attributes where the "x" is concerned should equal '1' then increment by 1 for each accordion item Trigger and Target elements e.g.- Item 1:
id="accordion-trigger-1"
/id="accordion-target-1"
- Item 2:
id="accordion-trigger-2"
/id="accordion-target-2"
- Item 3:
id="accordion-trigger-3"
/id="accordion-target-3"
- Item 1:
- The
tabindex
attribute for the Trigger element by default and when collapsed istabindex="-1"
, when expanded istabindex="0"
.
The accordion takes up one tab stop in the tab order. It can be navigated with the following shortcuts:
- Up or Left Arrow: move focus to the previous Trigger
- Down or Right Arrow: move focus to the next Trigger
- Space and Enter key: expand the currently focused Trigger
- Home: move focus to the first Trigger
- End: move focus to the last Trigger
The kitchen sink: Keyboard interaction.
If JavaScript is disabled then ALL of the Trigger elements should not be hidden. This can be achieved via js
and no-js
hooks (or whatever you wish to call them) being appended to the html
element. This simple snippet of JS placed directly after the opening head
element can be used:
<script>
(function(html) {
html.className = html.className.replace( /(?:^|\s)no-js(?!\S)/g , 'js' );
})(document.documentElement)
</script>
And your CSS might look something like:
/**
* The accordion target.
*
* N.B. targeted only at JS users.
*/
.js .c-accordion-target {
display: none;
// When the accordion target is expanded
&.is-visible {
display: block;
}
}
Consideration | Description | Yes/No/N.A. |
---|---|---|
Focusable | Can you get to the control via the keyboard?
Refer to Providing Keyboard Focus |
|
Operable | Can you use the control with the keyboard?
Refer to Keyboard Navigation |
|
Expected operation | Can you use the standard keys for the control type to operate it.
Refer to ARIA Widget Design Patterns |
|
Clear indication of focus | Can you easily see it when the control has focus?
Refer to Visible Focus (WCAG2) |
|
Label | The control has a text label that is exposed as an accessible name in accessibility APIs | |
Role | The control has an appropriate role exposed in accessibility APIs | |
States and properties | The control has any UI states and properties that it has exposed in accessibility APIs | |
Color contrast | The control label/description/icon is perceivable/usable for low vision users (Use a color contrast checker.) | |
High contrast mode | The control is perceivable/usable when High Contrast Mode is enabled (e.g. Windows HC mode) |