# Single-key shortcuts that can't be turned off

Source: https://easeweb.dev/learn/character-key-shortcuts
Topics: Keyboard and focus > Single-key shortcuts can be turned off (WCAG 2.1.4)
The fix: Either give the shortcut a modifier, such as Ctrl + K and ⌘K, or give people a setting that turns the single keys off. Ignoring key presses in text fields is needed too, but on its own it passes nothing: the keys still act everywhere else.
Test with: keyboard, speech input, screen reader
References: https://www.w3.org/WAI/WCAG22/Understanding/character-key-shortcuts.html https://www.w3.org/WAI/WCAG22/Techniques/general/G217 https://www.w3.org/WAI/WCAG22/Techniques/failures/F99 https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-keyshortcuts

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

## What happens

A shop's product page has a search box in its header, with / and S drawn in it as key caps. Press / or S anywhere on the page, unless you are typing in a field, and focus jumps to the search box. A customer who uses speech input adds the product to their basket and dictates a gift message: "thank you so much". Their last command left focus on the page rather than in the Gift message field, so the speech software types the words into the page, one key at a time. The first letters do nothing; the S of "so" moves focus to search, and "o much" is typed into the search box, which offers no results. The gift message stays empty. A keyboard user who starts typing before clicking into a field, or knocks the / key, lands in search in the same way.

## Why it fails

Success criterion 2.1.4 covers any shortcut made only of character keys: a letter, in upper or lower case, a number, punctuation or a symbol, including ones such as ? that need Shift to type. Such a shortcut passes only if people can turn it off, if they can remap it to include a key that types nothing, such as Ctrl or Alt, or if it works only while its component has focus. These two keys are listened for on the whole document and offer none of the three. The last option can't help here: a key whose job is to reach search from anywhere can't wait for search to have focus. Skipping key presses in text fields doesn't change the result: everywhere else on the page, / and S still act.

## Who is affected

The words aren't lost on screen, which makes the failure easy to miss: they sit in the search box, while the field they were meant for stays empty.

## What automation and AI miss

The markup is a labelled search field, so a static scan finds nothing wrong. The shortcut lives in a keydown handler, and only pressing keys shows it. Even then, a tool can't tell whether a setting somewhere on the site turns it off. Search widgets and AI coding tools add / as a search key readily, because large sites have it, and they usually add the check for text fields and stop there.

## Before: / and S jump to search from anywhere

```html
<form role="search" action="/search">
  <label for="search">Search</label>
  <input id="search" name="q" type="search">
  <kbd>/</kbd> <kbd>S</kbd>
</form>
```

```js
const search = document.getElementById('search');
document.addEventListener('keydown', (event) => {
  if (event.target.closest('input, textarea, select, [contenteditable]')) return;
  if (event.ctrlKey || event.metaKey || event.altKey) return;
  if (event.key === '/' || event.key === 's') {
    event.preventDefault();
    search.focus();
  }
});
```

Every / and S pressed outside a text field moves focus to search, and nothing turns that off. Dropping the S and keeping / is not a fix: / is a character key too, and speech input types it whenever someone says "slash".

## After: Ctrl + K, or ⌘K on a Mac

```html
<form role="search" action="/search">
  <label for="search">Search</label>
  <input id="search" name="q" type="search" aria-keyshortcuts="Control+K Meta+K">
  <kbd>Ctrl K</kbd>
</form>
```

```js
const search = document.getElementById('search');
document.addEventListener('keydown', (event) => {
  if (event.key.toLowerCase() !== 'k' || event.altKey || event.shiftKey) return;
  if (!event.ctrlKey && !event.metaKey) return;
  event.preventDefault();
  search.focus();
});
```

A shortcut that needs Ctrl or ⌘ is no longer a character key shortcut, so 2.1.4 no longer applies, and speech input never holds Ctrl while it types a sentence. The key still works from anywhere on the page, including inside other fields. Ctrl + K is the combination many sites and apps already use for search, so people may know it. `aria-keyshortcuts` tells screen reader users about it on the field it moves to; on a Mac, show ⌘K in the key cap instead.

## After: a setting that turns the single keys off

```html
<form role="search" action="/search">
  <label for="search">Search</label>
  <input id="search" name="q" type="search" aria-keyshortcuts="/ S">
  <span id="search-keys"><kbd>/</kbd> <kbd>S</kbd></span>
</form>
…
<label>
  <input type="checkbox" id="single-keys" checked>
  Keyboard shortcuts: / and S jump to search
</label>
```

```js
const search = document.getElementById('search');
const setting = document.getElementById('single-keys');
setting.checked = localStorage.getItem('single-keys') !== 'off';

// Show the keys, on screen and to screen readers, only while they work.
function showKeys() {
  if (setting.checked) search.setAttribute('aria-keyshortcuts', '/ S');
  else search.removeAttribute('aria-keyshortcuts');
  document.getElementById('search-keys').hidden = !setting.checked;
}
setting.addEventListener('change', () => {
  localStorage.setItem('single-keys', setting.checked ? 'on' : 'off');
  showKeys();
});
showKeys();

document.addEventListener('keydown', (event) => {
  if (!setting.checked) return;
  if (event.target.closest('input, textarea, select, [contenteditable]')) return;
  if (event.ctrlKey || event.metaKey || event.altKey) return;
  if (event.key === '/' || event.key === 's') {
    event.preventDefault();
    search.focus();
  }
});
```

The single keys stay for the people who use them, and anyone can turn them off, which is the first way to pass 2.1.4. It is not enough on its own, though: the keys are live until someone finds the setting, so a speech input user's words go on landing in search until they do. Put the setting where people will meet it, such as in the footer and on an accessibility page, and keep the choice with the account for signed-in customers. Starting with the keys off, and letting people turn them on, removes the gap.

## Which option to use

Both pass 2.1.4. Use Ctrl + K: the setting passes only once someone finds it, while Ctrl + K does the same job with nothing to find. Its costs are a two-key press, which someone typing with one finger or a mouth stick can manage with Sticky Keys, and the browser's own use of Ctrl + K, covered below. Keep single keys behind a setting only when your customers really use them, and then start them off. Deleting the shortcut also passes: the search box is a Tab or two away, and few shoppers know / is there.

## Implementation decisions

Ignore key presses in text fields with every fix, so people can type an S into a review or a gift message. That check is not a fix on its own: the Before already has it.

`aria-keyshortcuts` names a shortcut to assistive technology; it makes nothing work. Put it on the field the shortcut moves focus to, list only the keys that work right now, and remove it when the shortcut is turned off or changed. Show the same keys on screen as well, as the key cap in the search box, so sighted people learn them the same way.

Chrome and Firefox use Ctrl + K themselves, to search from the browser's address or search bar. While your page has focus, its handler takes the key; people can still reach the address bar with Ctrl + L. If you would rather not take it, another combination with Ctrl or ⌘ passes just as well, as long as you try it in every browser, operating system and screen reader you support. Check `ctrlKey` or `metaKey` together, so the same handler works on Windows, Linux and Mac.

Screen readers use single letters themselves in browse mode, such as H for the next heading, so the page never sees those presses; in focus mode, when the reader passes keys through, the page's shortcuts fire. Don't add `role="application"` to make your keys reach the page: it takes the reader's own keys away.

Some keys are easy to leave out when you list a page's shortcuts:

- Keys that need Shift to type, such as ? for a shortcut help dialog: they are character keys all the same.
- Sequences, such as G then C to go to the basket: each step is a character key, so the whole sequence is covered.
- Keys added by third-party scripts, such as a search widget's / or an embedded player's K to pause: check whether each acts only while its widget has focus, or can be turned off, and switch off any that act on the whole page.

## Verify the fix

1. With focus on the page outside any field, press / and S on their own: focus stays where it was. Where the fix is a setting, turn it off first, then reload and try again.
2. With speech input and focus outside any field, dictate a sentence with an S in it: nothing moves to search. Then move into the field and dictate again: the words land there.
3. Use the shortcut as intended, with Ctrl + K or ⌘K, or with the setting on, and confirm focus reaches search and the key cap shows the keys that work.
4. With a screen reader, confirm the search field announces its shortcut, and that the reader's own letter keys still move through the page in browse mode.

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after adding a shortcut or a third-party script.

## Limits

This is a starting pattern, not a guarantee for every application. The snippets leave out the search itself and saving the setting to a customer's account. Test the complete journey with a keyboard, speech input and your target assistive technology.
