Skip to content
easeweb
Search topics

Toolbars of clickable icons a keyboard can't reach

A photo editor's tools are icons in spans with click handlers, so Tab passes the whole toolbar and nothing tells a screen reader the tools are there.

WCAG 2.2
SC 2.1.1ASC 4.1.2A
Required by
Section 508 · EN 301 549 (EU)
Broken <span class="tool" data-action="rotate-left">
The accessibility problem illustrated: Motor:How do I turn the photo?
01

The problem

Keyboard and switch users can't reach or press any of a photo editor's tools, and screen reader users aren't told the tools are there or what they do.

02

Try it

The photo came out sideways. Turn it upright using only the keyboard.

Press Tab: focus goes straight past the six tools to Save photo, and the panel below never names one.

Apply a fix: as buttons, each tool is a Tab stop; as a toolbar, Tab stops once and the arrow keys, Home and End move between the tools.

Broken Can you fix this?

BrokenIcons in spans with click handlers

Edit photo

Screen reader says:

(Tab through the editor)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Make every tool a button named for what it does.

Before
BrokenIcons in spans with click handlers
<div class="photo-editor">  <img class="photo" src="/uploads/mug.jpg" alt="Enamel mug, front view">  <div class="toolbar">    <span class="tool" data-action="rotate-left">      <svg aria-hidden="true">…</svg>    </span>    <span class="tool" data-action="rotate-right">      <svg aria-hidden="true">…</svg>    </span>    <span class="tool" data-action="flip">      <svg aria-hidden="true">…</svg>    </span>    <span class="tool" data-action="zoom-in">      <svg aria-hidden="true">…</svg>    </span>    <span class="tool" data-action="zoom-out">      <svg aria-hidden="true">…</svg>    </span>    <span class="tool" data-action="reset">      <svg aria-hidden="true">…</svg>    </span>  </div>  <button type="button">Save photo</button></div>
What is wrong3 points
  • The tools respond only to click, on spans that take no focus, so no key reaches or presses them.
  • A span has no role, so no tool has one.
  • Each span's only content is an icon hidden from screen readers, so no tool has a name.
After

A button for each tool

<div class="photo-editor">  <img class="photo" src="/uploads/mug.jpg" alt="Enamel mug, front view">  <div class="toolbar">    <button type="button" class="tool" aria-label="Rotate left" data-action="rotate-left">      <svg aria-hidden="true">…</svg>    </button>    <button type="button" class="tool" aria-label="Rotate right" data-action="rotate-right">      <svg aria-hidden="true">…</svg>    </button>    <button type="button" class="tool" aria-label="Flip" data-action="flip">      <svg aria-hidden="true">…</svg>    </button>    <button type="button" class="tool" aria-label="Zoom in" data-action="zoom-in">      <svg aria-hidden="true">…</svg>    </button>    <button type="button" class="tool" aria-label="Zoom out" data-action="zoom-out">      <svg aria-hidden="true">…</svg>    </button>    <button type="button" class="tool" aria-label="Reset" data-action="reset">      <svg aria-hidden="true">…</svg>    </button>  </div>  <button type="button">Save photo</button></div>
How it is fixed3 steps
  1. Make each tool a native button. Tab reaches it, Enter and Space press it, and the browser turns both into the same click the script already listens for: the script doesn't change.
  2. Name each button for what it does with aria-label, so a screen reader says "Rotate right, button", and voice control users can say "Click Rotate right".
  3. In the CSS, reset the button's own look to the icon's, and add a focus ring.

This fixes the Before and passes 2.1.1 and 4.1.2. Six tools are six Tab stops between the photo and Save photo.

Why this fix: Use native HTML first

04

Design ideas

Any toolbar style can leave every tool in reach of a key.

Five ways to draw the photo tools. Try each with the mouse, then put the mouse aside and Tab through them: three can be reached and used from the keyboard, and two only with a mouse.

In the design file

  • Write each tool’s name beside its icon, even when the icon stands alone, since it becomes the name a screen reader reads and the tooltip.
  • Draw the focus ring on one tool, and note whether the row is one Tab stop moved with the arrow keys or a Tab stop per tool.
  • Draw a toolbar that appears on hover also as it shows on keyboard focus and on a touch screen.
  • Next to anything that is dragged, such as a dial, draw the buttons that do the same without dragging.

Passes

  • Icons with a word under each Each tool shows its name in small grey type under the icon, #5f6368, 6.05:1 on white, so nobody has to guess what a symbol means, and the same word is the name a screen reader reads and voice control listens for. It costs about 16px of height and wider tools; shorten a name rather than drop it.
  • A floating pill of grouped tools The tools float in a white pill over the bottom of the photo, always shown, with a thin rule between the turn, flip and zoom groups. It reads as one object, so it suits one Tab stop and the arrow keys; draw the ring round the focused tool, not round the whole pill.
  • 100%
    Zoom as a stepper that shows the level Zoom out and Zoom in sit either side of the level, 100%, in one rounded box, so people see what each press did. The level is plain text between two buttons, each with its own name, not a third control.

Fails

  • Tools that fade in when the photo is pointed atWCAG 2.1.1 A frosted bar slides up over the photo on hover and hides again when the pointer leaves. Nothing else shows it, so Tab passes every tool and a touch screen has no hover to show them; show it on keyboard focus too, and keep it shown on touch screens, as the floating pill does.
  • 0°
    A straighten dial you dragWCAG 2.1.1 A ruler under the photo that tilts it a degree at a time as it is dragged, as phone photo apps draw it. It follows the pointer only, so no key straightens the photo; let the arrow keys move it, or put buttons beside it that tilt it a degree at a time.
05

Verify the fix

4 checks, no mouse.

Test with: Keyboard, Screen reader, Speech input, Forced colors, Zoom

0 of 4 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the toolbar, its component or its library changes.

Limits

This is a starting pattern, not a guarantee for every application. The toolbar script is a minimal sketch: it has no disabled tools, no vertical orientation and no controls other than buttons. The typing area of an editor, and its name, are covered in rich text editors announced without their label, and a single control built from a div in div buttons that can't be reached with Tab. The same one-Tab-stop pattern, for a sidebar, is shown in tree views keyboards can't open and screen readers flatten. Test the complete journey with your target assistive technology.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

EaseWeb service

Fixed it? Keep it from coming back.

I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.

See the service