Skip to main content
WCAGrules
Quick navigation

Keyboard

Every function on the page has to be operable through a keyboard interface. That phrase is a defined one, and it matters. A keyboard interface is the software channel that receives keystrokes rather than a physical keyboard, so a phone has one. A keyboard-driven mouse emulator such as MouseKeys does not count as one, because it drives the page through the pointer interface underneath, which means the answer that people can still get around with MouseKeys is not an answer. One exception exists and it is narrow. A function is out of scope only where the underlying task depends on the path your movement traces, which covers freehand drawing and painting. Drawing a straight line, resizing a window and dragging an object somewhere the route does not matter are all named as not path-dependent. Drag and drop therefore sits inside this rule. A second clause is easy to miss. No individual keystroke may require a specific timing, so a key you have to hold down before it registers, or a pattern you have to repeat quickly, fails here too.

Why it matters

The keyboard interface is the shared channel almost every assistive technology speaks through. Screen readers, speech input software, sip-and-puff systems, on-screen keyboards, scanning software and alternate keyboards all send keystrokes, so they all inherit whatever keyboard support you built. Low-vision users belong on that list as well, because tracking a moving pointer is hard work and the keyboard is often the easier route, sometimes the only one. So a single mouse-only tile dropped into a checkout does not slow those visitors down. It ends the purchase. That is the point where an accessibility claim stops being a slogan and turns into something a person can actually do.

Who this rule protects

This affects blind users driving a screen reader from the keyboard, speech-input users whose software sends keystrokes on their behalf, people using sip-and-puff systems, on-screen keyboards, scanning software or an alternate keyboard, people with tremors or limited hand dexterity, and low-vision users who find tracking a pointer harder than pressing a key.

How to check it yourself

  1. Unplug the mouse and finish your top task with the keyboard alone, from search to add to cart to payment. The task is what gets tested, not the inventory of controls.
  2. Judge each blocked step against the right bar. The rule does not ask that every mouse-operable control be reachable by Tab, only that a keyboard user can do the same or a comparable thing. A search form whose submit button takes a click and nothing else still passes, as long as pressing Enter in the text field submits it.
  3. Scroll every panel that has its own scrollbar using the keyboard alone, in the browsers your readers actually use. Chrome now makes a scrolling container focusable by itself when nothing inside it is focusable, and browsers that do not leave the panel unreachable. Test the behaviour rather than the markup, and add tabindex="0" where the panel does not answer the keyboard.
  4. Tab into every iframe and confirm none of them has been pulled out of the tab order with tabindex="-1" while it still holds links or fields.
  5. Look for anything that needs a held or a hurried key, such as hold to confirm, or a second press within a moment. A timing requirement on a single keystroke fails this rule on its own.

Failures we see most often

  • Controls wired only to pointer events. A clickable <div> with an onclick handler and no key handling looks like a button, sits nowhere in the tab order, and cannot be activated by any keyboard user. This is the most common way the rule breaks.
  • Script that pushes focus away the moment an element receives it, so the element can never be landed on. The same line of code breaks focus visibility and focus order alongside it.
  • Links faked out of spans and divs. The click works, the keyboard does not, and the same markup hides the control's role from assistive technology.
  • Hover-only menus that open for a pointer and never open for focus, since a key press has no hover to trigger.
  • A scrolling region built from a plain container with no focusable content inside it and no tabindex, in a browser that does not focus such panels on its own, so its content is unreadable without a mouse wheel.

Who this one is for

Read from this rule's own note above, so the grouping and the note cannot disagree.

How this one is tested

We list 2 ACT rules against 2.1.1. Each one defines exactly what a checker looks at, which is how automated tools decide what to flag. Each one also checks a slice, so passing every rule here is not the same as meeting the criterion, and a rule can be proposed rather than approved or need a person to finish it. The note beside each says which.

How to fix it

  • Build from native HTML first. <button>, <a>, <select> and <input> arrive with keyboard support, focus behaviour and a role already attached, which is four problems solved by one decision.
  • Where a custom widget is unavoidable, tabindex="0" is a third of the job. Add the ARIA role and the key handling from the Authoring Practices patterns as well, because a focusable element with no role passes this rule and fails 4.1.2 on the same page.
  • Give any scrollable container tabindex="0" when it holds no focusable children and your target browsers do not focus it for you. That is a compatibility measure rather than a markup rule the standard states, and it costs nothing where the browser already handles it.
  • Treat hover and focus as a pair. Whatever the interface does on mouse hover, make it do on keyboard focus, and the menu opens for everybody.
  • Follow the platform conventions even though the rule does not force you to. A control that answers Enter and ignores Space still conforms, and it still surprises everybody who tries it.
Step-by-step fix guides (13)

Passes vs. fails

A general illustration of the pattern rather than a test of 2.1.1. Passes: reachable, visible, activatable. Fails: a div the keyboard cannot reach.

Passes

<button onclick="selectSize('M')">M</button> lands in the tab order, announces itself as a button, and fires on Enter like every other control on the page.

Fails

<div onclick="selectSize('M')">M</div> looks like a size button and behaves like one for a mouse. Tab skips straight past it, so a keyboard user never picks a size and never buys the product.

In audits and lawsuits

We test this on your real revenue journeys, meaning search, add to cart and checkout, rather than on components in a lab, and every failure ships with a screenshot of the exact step where the journey dies. Three things get checked that a quick tab-through misses. A PDF served from your site is a web page for this rule and carries the same duty, and three of the nine documented techniques are written for PDFs specifically. A scrolling panel with no focusable children inside it cannot be scrolled by keyboard in browsers that have not yet made those panels focusable on their own, which stays invisible until somebody tries. And we switch on the operating system's own keyboard features, because a site that breaks under Sticky Keys is breaking for the people most likely to have it turned on.

Go somewhere useful

Find tools, resources and your workspace.

29 destinations