Practice: fix a component

Take one component that works only with a mouse and make it work for everyone.

16of 16
≈ 15Min read
4Parts

The component

A navigation menu that opens on hover, built from divs. It looks right, it demonstrates well, and it cannot be used with a keyboard, cannot be announced, and disappears the moment somebody with a tremor moves the pointer a few pixels.

This is the most common broken component on the web, and rebuilding it uses every lesson in this course.

What it has to become

  • A real <button> that opens and closes it, with aria-expanded kept true and aria-controls pointing at the panel.
  • A real list of real links inside the panel — not divs with click handlers.
  • Opening and closing on click, not hover. Hover may open it as well, but it must never be the only way.
  • Escape closes it, and focus returns to the button.
  • When it is closed the links are not reachable by Tab; when it is open they are.
  • Everything named, and the button’s name says what it opens.

Why not hover

Hover cannot be triggered by a keyboard, is unreliable with a touch screen, and requires a steady pointer for as long as the menu is open. WCAG 2.1 added a criterion for exactly this: content that appears on hover must be dismissible, hoverable and persistent — which a click-to-open disclosure gets for free.

If the design insists on hover, add it on top of the click behaviour, with a delay before it closes.

The order to work in

Semantics first — put the right elements in. Then state — aria-expanded, and hiding the panel properly with hidden rather than opacity: 0, which leaves everything reachable. Then keys — Escape, and focus back. Then check it with Tab, then with a screen reader.

That order matters: half the ARIA you were about to write turns out to be unnecessary once the elements are right.

Practice