Accordion

How the Accordion works with a keyboard and assistive tech, and where it stands against WCAG 2.2 AA.

AAWCAG 2.2 target
18/21contrast pairs passing
4keyboard interactions

Each Accordion header is a native <button> inside a heading, so the browser supplies its role, focus and keys. The component adds the disclosure state, ties each header to its panel, and keeps a closed panel out of reach. It follows the WAI-ARIA Accordion pattern and is held to WCAG 2.2 AA.

Keyboard#

Tab

Moves to the next header, or into the content of an open panel. A closed panel and a disabled header are skipped.

Shift+Tab

Moves focus back the same way.

Enter

Opens or closes the panel under the focused header.

Space

Opens or closes the panel under the focused header.

Semantics#

<h3><button type="button">

The header is a button inside a heading, so it can be found by heading navigation. h3 is the preview's level; set the level to fit the page outline.

Always
aria-expanded

true while the panel is open, false while it is closed. This is the state; the plus, minus and chevron only echo it.

Always
aria-controls

Points at the panel's id.

Always
role="region"

Labelled by its header through aria-labelledby. With many panels open at once, drop the role so the landmarks list does not fill up.

Panel
inert

The panel stays in the page so its height can animate, but nothing inside it can be focused or read until it opens.

Closed
disabled

The header is removed from the tab order and can't be toggled.

Disabled
aria-label="Collapse"

The 48px button is named by the title while closed and by collapseLabel while open. Pass a label that names the section, such as Collapse Billing.

2.0, open
aria-hidden="true"

The toggle glyph and the info icon are decorative.

Glyphs

Colour contrast#

Every variant and state has to meet WCAG 2.2 Level AA. Measure the colours as they land on screen: a translucent hover or press wash over whatever sits behind it.

4.5:1

Header text · Default, Hover, Open

The title against the card in every state, with the hover wash laid over white. Titles are 16–18px Medium, below the large-text threshold, so 4.5:1 applies.

WCAG 1.4.3 Contrast (Minimum) ↗
4.5:1

Panel text and link · Open

Body copy is #2a2a2a or #6d6d6d on white (5.17:1 for the lighter one). The 3.0 read-only card is #f2f2f2, where #6d6d6d measures 4.62:1. The 2.0 link is #005cf8 on white, 5.40:1.

WCAG 1.4.3 Contrast (Minimum) ↗
3:1 if needed

Toggle glyph · Default

The plus or chevron is #8f8f8f on white, 3.23:1. It is decorative, since aria-expanded carries the state and the open panel shows it, but it still clears 3:1. The 3.0 red toggle measures 3.64:1.

WCAG 1.4.11 Non-text Contrast ↗
3:1

Focus indicator · Focus visible

A 2px #1a6ef8 ring 2px off the whole card, on keyboard focus only: 4.54:1 against white.

WCAG 1.4.11 Non-text Contrast ↗WCAG 2.4.13 Focus Appearance ↗
Not required

Disabled · Disabled

Inactive headers are exempt. The disabled card is #fcfcfc with a #6d6d6d title and a #cbcbcb toggle.

WCAG 1.4.3 Contrast (Minimum) ↗

Measured contrast#

Header text against the card in each state, with hover washes laid over white; the [05] badge is measured against its own pale green fill. 3 of 21 pairs fall below their minimum (4.5:1 for text, 3:1 for graphics) and are marked in amber.

Set · partDefaultHoverOpen
Normal [01] · title14.35passes12.04passes5.17passes
Normal [02] · title14.35passes10.98passes5.17passes
Normal [03] to [05] · title14.35passes12.04passes14.35passes
Normal [05] · badge3.56below the minimum3.56below the minimum3.56below the minimum
2.0 Grey · title12.82passes12.82passes14.35passes
2.0 Brand · title12.77passes8.24passes14.35passes
3.0 · title14.35passes13.99passes14.35passes

Motion#

  • A panel opens and closes with a 220ms height change; under prefers-reduced-motion it snaps open and shut.
  • Hover colour changes take 150ms and are also turned off under reduced motion.

Checklist#

Set the heading level to fit the page: an accordion under an h2 uses h3 headers.

Header text says what is in the panel, so people can choose without opening every one.

The [05] badge, #229a14 on #f4fef2, measures under 4.5:1. Use a darker green for its text before the code library ships.

Up, Down, Home and End between headers are optional in the WAI-ARIA pattern and are not provided; Tab reaches every header.

In 2.0, give collapseLabel the section's name. Several buttons all called Collapse can't be told apart in a list of controls.

Don't hide content everyone needs behind a header; a search on the page can't find text in a closed panel.