2.1.4 Character Key Shortcuts
WCAG 2.2 · 2.1.4 A Operable
What it requires
If a keyboard shortcut is implemented using only letter (including upper- and lower-case), punctuation, number, or symbol characters, then at least one of the following must be true:
- Turn off: a mechanism is available to turn the single-character shortcut off.
- Remap: a mechanism is available to remap the shortcut to use one or more non-printable keys (such as Ctrl, Alt, or Cmd).
- Active on focus: the shortcut for a user-interface component is active only when that component has focus.
The point is to prevent shortcuts that fire from a single character key from being triggered accidentally anywhere on the page.
- Speech-input users — dictation software emits stray characters that can unintentionally trigger single-key shortcuts.
- People with motor disabilities or tremors who make inadvertent keystrokes.
- Screen-reader users, whose AT already reserves single keys for navigation; a conflicting page shortcut can hijack those keys.
How to detect it
| Check | How |
|---|---|
| Find the shortcuts | Review docs, a “keyboard shortcuts” panel, and code for global keydown /
keypress handlers that act on single printable keys. |
| Manual keyboard | With no field focused, press the suspect keys (e.g. j, /) and confirm whether an action fires page-wide. |
| Off / remap | Look for a setting to disable or rebind shortcuts. Confirm it actually works. |
| Focus scope | If neither off nor remap exists, verify the shortcut only fires while its component is focused. |
| Automated tools | Largely a manual check. Tools like axe cannot reliably detect custom JS shortcuts, so do not rely on them here. |
How to fix it
- Inventory every single-character shortcut on the page.
- Prefer adding a modifier key (Ctrl/Alt/Cmd) so the shortcut is no longer character-only.
- Otherwise, provide a clearly labelled setting to turn shortcuts off or remap them.
- Or restrict the shortcut to fire only when its component has focus by binding the listener to that element rather than the document.
Below, the listener is scoped to the focused component instead of the whole document, so it satisfies the “active on focus” option:
<div class="editor" tabindex="0">…</div>
<script>
const editor = document.querySelector('.editor');
// Bound to the component, not document — only active on focus
editor.addEventListener('keydown', (e) => {
if (e.key === 'b' && !e.ctrlKey && !e.altKey) toggleBold();
});
</script>
Copy-paste tests
Automated coverage
There is no fully automated axe-core rule for 2.1.4 — character key shortcuts depend on runtime keyboard behaviour, so this criterion needs manual review using the console check and steps below.
Run this in the browser console
// Read-only: surfaces nodes that may bind single-character key shortcuts.
const attrHits = [...document.querySelectorAll('[accesskey]')];
const hooks = [...document.querySelectorAll('[data-shortcut],[data-key],[data-hotkey],[onkeypress],[onkeyup],[onkeydown]')];
const suspects = [...new Set([...attrHits, ...hooks])];
console.log('accesskey nodes:', attrHits.length, 'inline/handler hints:', hooks.length);
console.table(suspects.map(el => ({
tag: el.tagName.toLowerCase(),
accesskey: el.getAttribute('accesskey'),
hint: el.getAttribute('data-shortcut') || el.getAttribute('data-key') || el.getAttribute('data-hotkey') || '',
text: (el.textContent || '').trim().slice(0, 40)
})));
suspects.forEach(el => el.style.outline = '2px solid magenta'); // visual only, not saved
What to check manually: press single letter/number/symbol keys while focus is in the page body and confirm nothing triggers unexpectedly; for any real shortcut, verify it can be turned off or remapped, or only fires while its component has focus.
Related
- WCAG 2.2 criteria index — all success criteria.
- Learn catalog — every lesson tagged with its criteria.
- Keyboard & focus — operable interaction, focus scope, and keyboard handling.