Level A

30.6% of home pages expose an empty button -- a control a keyboard user can focus but not identify

2.1.1 Keyboard

In Plain Language

WCAG 2.1.1 Keyboard (Level A) requires that every piece of functionality on the page be operable through a keyboard interface, without requiring specific timings for individual keystrokes [1]. "Functionality" means anything a user can do -- following a link, submitting a form, opening a menu, dragging a card between columns, playing a video. If a mouse user can do it, a keyboard user must be able to do it too.

The normative text carves out one narrow exception: input that depends on the path of the user's movement, not just the endpoints. Freehand drawing in a watercolor app qualifies, because the brushstroke itself is the content. Drag-and-drop does not qualify -- the start and end positions are what matter, so a keyboard-operable alternative (cut/paste, move-up/move-down buttons, a destination picker) is required [1].

Native HTML interactive elements -- <button>, <a href>, <input>, <select>, <textarea>, <summary> -- are keyboard-operable by default. Tab moves focus to them, Enter or Space activates them, and the browser handles the rest. 2.1.1 failures almost always come from custom widgets that replace or override these native elements.

Why It Matters

  • Keyboard-only operation is the access path for a large and varied population. Blind users navigate with a screen reader that consumes keyboard events exclusively -- there is no pointer to aim. Low-vision users running screen magnification lose the cursor constantly and rely on Tab to move predictably. Users with motor disabilities who cannot operate a mouse reach the page through switch devices, sip-and-puff controllers, eye-tracking systems, and voice-control software -- all of which emit keyboard events under the hood. Users with temporary injuries (a broken arm, repetitive strain) fall back to the keyboard. Power users on any device drive the page from the keyboard for speed. Devices without a pointing device at all -- kiosks, some TVs, some embedded browsers -- are keyboard-only by construction.
  • The mechanism that breaks 2.1.1 is almost always the same: a developer reaches for <div> or <span> with a click handler instead of a native interactive element. <div onclick> is not in the tab order, does not fire on Enter or Space, and exposes no role to assistive technology. A keyboard user cannot reach it, and if they could, they could not activate it. Related failure modes: a custom keydown listener that only fires on one specific key (Enter but not Space); a modal overlay that accepts focus but has no Escape handler and no focus trap, so Tab leaks into the hidden page behind it; a JavaScript event.preventDefault() on Tab that strands focus in place; a scripted focus move that lands on a non-focusable target and drops focus to <body>.
  • Empty or unlabeled controls are the visible edge of the same problem. WebAIM Million 2026 found empty buttons on 30.6% of home pages and empty links on 46.3% [2] -- controls a keyboard user can focus but not identify, because the accessible name is missing. The control is technically operable but functionally opaque.

Examples

Do: Use native interactive elements

Native HTML controls are in the tab order, expose the right role to assistive technology, and fire on Enter or Space without any JavaScript. This is the First Rule of ARIA Use: if a native element exists, use it [3].

<!-- Keyboard-operable with zero JavaScript -->
<button type="button" onclick="save()">Save</button>
<a href="/dashboard">Dashboard</a>
<input type="text" name="search" />
<select name="country">
  <option value="us">United States</option>
  <option value="ca">Canada</option>
</select>
Don't: Click handler on a non-interactive element

A <div> is not focusable, has no implicit role, and does not respond to Enter or Space. A keyboard user cannot tab to it and cannot activate it. Adding onclick does nothing for keyboard operation -- the browser only fires click from the keyboard for elements that are already interactive.

<!-- FAIL: not in the tab order, no keyboard activation -->
<div onclick="save()">Save</div>

<!-- FAIL: mousedown only, no keyboard equivalent at all -->
<span onmousedown="openMenu()">Menu</span>
Do: If you must build a custom widget, follow the APG pattern

When a native element will not do the job, the WAI-ARIA Authoring Practices Guide specifies which role, which keys, and which state updates a given pattern requires -- button, combobox, dialog, menu, tabs, tree, and so on [6]. The minimum for a custom button: role="button", tabindex="0", and a keydown handler that fires on both Enter and Space.

<div role="button"
     tabindex="0"
     onclick="save()"
     onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); save(); }">
  Save
</div>

<!-- Still better: delete the div and use <button>. -->
Don't: Modal dialog with no keyboard exit

The modal takes focus when it opens but provides no Escape handler and no close button. A keyboard user can reach the modal content but cannot dismiss it. Paired with 2.1.2 No Keyboard Trap, this is the canonical blocking failure -- the user is stuck.

<div class="modal" role="dialog" aria-modal="true">
  <h2>Confirm action</h2>
  <p>Are you sure?</p>
  <!-- no close button, no Escape handler, no focus trap -->
</div>

How to Fix It

  1. Reach for a native element first. <button>, <a href>, <input>, <select>, <textarea>, and <summary> are in the tab order, expose the correct role, and fire on Enter or Space without any custom JavaScript. This is the First Rule of ARIA Use: if a native element with the semantics and behavior you need already exists, use it instead of repurposing a different element with ARIA [3].
  2. If a custom widget is unavoidable, follow the WAI-ARIA Authoring Practices Guide pattern for its role. The APG specifies, for each widget type (button, menu, combobox, listbox, tabs, dialog, tree, grid), which keys must be handled, which ARIA attributes must be set, and how state must change in response [4]. Do not invent a pattern -- match an existing one so assistive-technology users hit the interaction model they already know.
  3. Add tabindex="0" to include a custom element in the tab order. Never use positive tabindex values -- they override the document order and create focus sequences that diverge from the visual layout, which breaks 2.4.3 Focus Order.
  4. Handle both Enter and Space on activation. Native buttons fire on both. A custom button that only listens for Enter silently fails for screen-reader users who have been trained to press Space.
  5. Do not require specific keystroke timing. 2.1.1 explicitly forbids requiring a keypress within a timing window. A user on a switch device may take seconds between keystrokes. If the interaction needs a timeout at all, make it user-adjustable (see 2.2.1 Timing Adjustable).
  6. Never suppress focus. outline: none without a replacement focus style, or script that calls blur() on every focus event, makes the page unusable for keyboard navigation even when the underlying controls are correct.
  7. Test with the mouse unplugged. Navigate the entire page using only Tab, Shift+Tab, Enter, Space, the arrow keys, and Escape. Every interactive element must be reachable, must expose a visible focus indicator, and must be operable -- including inside modals, menus, carousels, and custom widgets.

References

  1. [1] W3C (2023). Understanding Success Criterion 2.1.1: Keyboard. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html
  2. [2] WebAIM (2026). The WebAIM Million: An accessibility analysis of the top 1,000,000 home pages. WebAIM, Accessed 2026-04-07. https://webaim.org/projects/million/
  3. [3] W3C (2026). ARIA in HTML. W3C, Accessed 2026-04-07. https://www.w3.org/TR/html-aria/
  4. [4] W3C (2023). Understanding Success Criterion 1.1.1: Non-text Content. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html
  5. [5] W3C (2023). Understanding Success Criterion 1.4.3: Contrast (Minimum). W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
  6. [6] W3C (2024). WAI-ARIA Authoring Practices Guide. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/ARIA/apg/