Operable · 2.1 Keyboard Accessible

Keyboard WCAG 2.1.1 · Level A

All functionality must be operable with a keyboard interface, without requiring specific timing for individual keystrokes. The only exception is a function whose input depends on the path of the user's movement, not just its endpoints, such as freehand drawing.

Level
A
Since
WCAG 2.0
Principle
Operable
Guideline
2.1 Keyboard Accessible

Live demo

Buy a shirt with the keyboard only

The same task, done two ways: switch between the version that passes and the one that fails, or put them side by side. Everything in the box is live, so try it with a keyboard, a pointer or a screen reader.

Use only Tab, Enter and Space to pick a size and add the shirt to your basket, then switch to Fails and try again. The Show tab order button numbers every control that Tab can reach.

Live example

Passes

Linen shirt

The shirt costs $38. Choose a size, then add it to your basket.

Size

What happened

    Why it passes

    Every size and the Add to basket button is a real button, so Tab reaches each one and Enter or Space works just as a click does.

    Why it fails

    The sizes are plain text that Tab skips, and Add to basket takes focus but ignores Enter and Space. Without a mouse you cannot buy the shirt.

    Examples

    Code that fails, and the fix

    Five examples, each one running: the usual ways this criterion fails, and code that passes. Listen to them, measure them, or copy the code.

    01What changes 2 lines

    Fails

    Clickable div used as a button

    Live preview

    HTML
    <div class="button" onclick="addToBasket('linen-shirt')">  Add to basket</div>

    A div is not focusable and has no key handling, so Tab never reaches it and Enter or Space cannot trigger it. Only a mouse can add the shirt to the basket.

    Passes

    Real button with the same handler

    Live preview

    HTML
    <button type="button" class="button" onclick="addToBasket('linen-shirt')">  Add to basket</button>

    A button is in the tab order, and browsers fire its click event on Enter and Space, so one click handler serves mouse and keyboard users alike (technique SCR35).

    02What changes 4 lines

    Fails

    Row actions shown only on hover

    Live preview

    CSS
    .order-row .row-actions {  display: none;}.order-row:hover .row-actions {  display: flex;}

    The Edit and Delete buttons exist only while the mouse is over the row. With display: none they are out of the tab order, so a keyboard user never reaches them.

    Passes

    Row actions also shown on focus

    Live preview

    CSS
    .order-row .row-actions {  opacity: 0;}.order-row:hover .row-actions,.order-row:focus-within .row-actions {  opacity: 1;}

    The buttons stay in the tab order and become visible as soon as keyboard focus moves into the row, as well as on hover.

    Passes

    Custom slider that answers the keyboard

    Live preview

    JavaScript
    // <div id="max-price" role="slider" tabindex="0" aria-label="Maximum price"//   aria-valuemin="0" aria-valuemax="500" aria-valuenow="200"></div>const slider = document.getElementById("max-price");const steps = { ArrowRight: 10, ArrowUp: 10, ArrowLeft: -10, ArrowDown: -10, PageUp: 50, PageDown: -50 };slider.addEventListener("keydown", (event) => {  let value = Number(slider.getAttribute("aria-valuenow"));  if (event.key in steps) value = Math.min(500, Math.max(0, value + steps[event.key]));  else if (event.key === "Home") value = 0;  else if (event.key === "End") value = 500;  else return;  event.preventDefault();  slider.setAttribute("aria-valuenow", value);  slider.setAttribute("aria-valuetext", "$" + value);});

    Arrow keys, Page Up, Page Down, Home and End change the value, so the price filter works without dragging. Mouse users can still drag the thumb.

    Why it matters

    Who it helps

    People who are blind, have limited dexterity or tremor, or use switch devices, speech input or on-screen keyboards rely on keyboard input. Anything that works only with a mouse locks them out.

    W3C: Understanding 2.1.1
    • Level A

      Level A is the minimum: failing it can shut some people out completely.

    • In WCAG versions

      Part of WCAG 2.0 since December 2008, and of every version after it.

      WCAG 1.0 checkpoints: 1.2, 6.4, 9.1, 9.2, 9.3

    • Where it is required

      Required where the law names WCAG 2.0 or later at this level: the United States, Canada, the European Union, the United Kingdom, France, Germany, Italy, Spain, the Netherlands, Ireland, Norway, Switzerland, India, Japan, Australia, New Zealand and Israel.

    How to test

    Checking it

    A few concrete steps. Automated tools find some failures; most need a person.

    1. Put the mouse aside and use Tab, Shift+Tab, Enter, Space, the arrow keys and Escape to reach and operate every link, control and widget.
    2. Confirm that anything possible with a mouse, such as opening menus, reordering items by dragging or setting a custom slider, can also be done from the keyboard.
    3. Check that no action requires pressing keys at a particular speed or holding them for a set length of time.

    Common failures

    Where it breaks

    • A clickable div or span has a mouse click handler but no keyboard focus or key handling, so keyboard users cannot reach or activate it.
    • A custom dropdown, slider or date picker responds only to mouse events.
    • Edit and delete buttons appear only when a row is hovered with the mouse, so keyboard users never reach them.