WCAG 2.1.1 · Level A · EN 301 549 9.2.1.1

Keyboard

Requires that every function can be operated from a keyboard, without needing specific timings for individual keystrokes.

In brief

Many people never use a mouse or a touch screen. Screen reader users, people with motor disabilities, people with tremors and anyone who uses a switch, a sip-and-puff device or voice control all rely on the keyboard or on something that behaves like one. If a function works only with a pointer, they cannot use it.

This criterion requires that all functionality is operable through a keyboard interface, without requiring specific timings for individual keystrokes. The exception is functionality that depends on the path of the movement, such as freehand drawing, not just on its end points.

What does it cover?

  • All functions: Links, buttons, form controls, menus, dialogs, tabs, sliders, carousels and every other control must work from the keyboard.
  • Native elements first: a, button, input, select and textarea are keyboard accessible by default. Custom controls must reproduce their behavior.
  • Standard keys: Tab and Shift+Tab to move, Enter and Space to activate, arrow keys inside widgets such as menus, tabs and radio groups, Escape to close.
  • Hover and drag: Content that appears on hover must be reachable from the keyboard, and drag-and-drop needs a keyboard alternative.
  • Exception: Functionality whose underlying task depends on the path of the movement, such as freehand drawing. Typing in a text field is not an exception.
  • Out of scope: Getting stuck in a component is 2.1.2. Single-key shortcuts are 2.1.4. The order of focus is 2.4.3 and its visibility is 2.4.7.

Who does it affect?

Screen reader users, who navigate with the keyboard. People with motor disabilities who cannot use a mouse. People who use switches, eye trackers, voice control or on-screen keyboards. People with tremors. Power users who prefer the keyboard.

In the EAA and EN 301 549

The European Accessibility Act (Directive (EU) 2019/882) applies to in-scope products and services placed on the market after 28 June 2025. Recital 47 names four principles for websites and mobile applications: perceivable, operable, understandable and robust. Operability by keyboard is part of "operable".

The technical counterpart is the standard EN 301 549, which incorporates WCAG 2.1.1 by reference and turns it into separate clauses for each kind of ICT.

Where WCAG 2.1.1 appears in EN 301 549
ClauseType of ICTWhat it requires
9.2.1.1Web pagesWeb content must satisfy WCAG success criterion 2.1.1.
10.2.1.1Non-web documents (PDF, Office files)Documents must be operable through a keyboard interface where the standard applies the criterion to them.
11.2.1.1Non-web software (native mobile apps)Software must be operable through a keyboard interface (for native apps: a hardware keyboard, switch or similar).

Whether and how the criterion applies to non-web documents is stated in clause 10 of the standard. Clause numbers follow the "9. + WCAG number" pattern of EN 301 549. In V3.2.1 the software clause is divided into further subclauses for open and closed functionality. Check the exact numbers in the standard when you cite them.

Standard version: EN 301 549 V4.1.1 (September 2026) is based on WCAG 2.2 and is the first version prepared specifically for the EAA. It has not yet been cited in the Official Journal of the European Union, so for now it is best treated as a voluntary technical route to the EAA's requirements. Once cited, it will give a presumption of conformity. The text of criterion 2.1.1 is the same in WCAG 2.1 and 2.2.

A note on EAA scope: Article 2(4) of the Directive excludes certain content from the requirements, for example office file formats published before 28 June 2025 and archives that are not updated after that date. Content you publish or change after that date is not covered by these exclusions.

Directive (EU) 2019/882, EUR-Lex, opens in a new tab

Code examples for the web

1. Use a real button

A div with a click handler is not focusable and does not react to Enter or Space.

Incorrect
<div class="btn" onclick="save()">Save</div>
Correct
<button type="button" onclick="save()">Save</button>

2. If you must use a custom element

Give it a role, make it focusable and handle Enter and Space.

Incorrect
<span onclick="toggle()">Menu</span>
Correct
<span role="button" tabindex="0" onclick="toggle()"
      onkeydown="if (event.key === 'Enter' || event.key === ' ') {
        event.preventDefault(); toggle();
      }">Menu</span>

3. Links that go somewhere

An anchor without an href is not focusable.

Incorrect
<a onclick="openPage()">Pricing</a>
Correct
<a href="/pricing">Pricing</a>

4. Hover menus

Show the submenu on focus as well as on hover.

Incorrect
.nav li:hover > ul { display: block; }
Correct
.nav li:hover > ul,
.nav li:focus-within > ul { display: block; }

5. Scrollable regions

A region that scrolls but contains no focusable content cannot be scrolled with the keyboard in some browsers. Make it focusable.

Incorrect
<div class="log" style="overflow:auto; height:200px">…</div>
Correct
<div class="log" style="overflow:auto; height:200px"
     tabindex="0" role="region" aria-label="Activity log">…</div>

6. Drag and drop

Offer buttons or keys that do the same thing.

Incorrect
<li draggable="true">Item</li> <!-- only draggable -->
Correct
<li>
  Item
  <button aria-label="Move item up">↑</button>
  <button aria-label="Move item down">↓</button>
</li>

Code examples for mobile

Native apps are operated with external keyboards, switch control and full keyboard access. Use standard controls so they work with these inputs, and avoid gestures with no equivalent action.

iOS (SwiftUI)

import SwiftUI

struct SaveRow: View {
    var body: some View {
        // Avoid: a tap gesture on a Text is not reachable with Full Keyboard Access
        // Text("Save").onTapGesture { save() }

        // Use a Button: focusable, activatable with Space and VoiceOver
        Button("Save") { save() }

        // For custom gestures, add an equivalent action
        Text("Archive")
            .onTapGesture { archive() }
            .accessibilityAddTraits(.isButton)
            .accessibilityAction(named: "Archive") { archive() }
    }
}

Android (Jetpack Compose)

import androidx.compose.foundation.clickable
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role

@Composable
fun SaveRow() {
    // Avoid: pointerInput { detectTapGestures { ... } } on a Text,
    // which a keyboard or switch cannot trigger

    // Use a Button, or clickable with a role: focusable and activated with Enter/Space
    Button(onClick = { save() }) { Text("Save") }

    Text(
        "Archive",
        modifier = Modifier.clickable(role = Role.Button) { archive() }
    )
}

How to test

  • Put the mouse away: Use only Tab, Shift+Tab, Enter, Space, arrow keys and Escape. Can you do everything a mouse user can do?
  • Reach every control: Tab through the whole page. Is every link, button, field and menu reachable?
  • Activate everything: Does each control respond to Enter or Space as expected? Do menus, tabs and sliders respond to arrow keys?
  • Check hover content: Can you reach and open submenus, tooltips and other hover content using only the keyboard?
  • Check custom widgets: Compare each custom control with the pattern in the WAI-ARIA Authoring Practices.
  • Check mobile: Connect a keyboard or turn on Full Keyboard Access or a switch. Can you complete the main tasks?
  • Use a checker as a starting point: Automated tools find missing roles and focusability but cannot tell whether a function really works with the keyboard.

Common mistakes

  • Clickable div and span elements: The most frequent failure of this criterion.
  • Links without href: Not focusable.
  • Click handlers only: Keyboard events are never fired for mouse-only handlers.
  • Hover-only menus and tooltips: Keyboard users never see them.
  • Drag and drop with no alternative: There is no keyboard way to do the same job.
  • tabindex values above 0: They scramble the focus order.
  • Removing the outline without a replacement: Users cannot see where focus is (2.4.7).
  • Keyboard handlers that ignore Space: Buttons must respond to both Enter and Space.

Sources

Standard version: EN 301 549 V4.1.1 (2026-09), WCAG 2.2. This page is for informational purposes only and is not legal advice. For binding requirements, refer to the official texts of the European Accessibility Act (Directive (EU) 2019/882) and EN 301 549.

Corpowid is recognized by Gartner

Corpowid has been recognized by Gartner, a leading global research and advisory firm, for our innovation and performance in digital accessibility. These badges reflect our commitment to creating inclusive, AI-powered web experiences.

Have questions about Corpowid?

Let’s connect.

We will get back to you as soon as possible.