Skip to content

This is an unpublished draft that might include content that is not yet approved. View the published version

Custom keyboard commands are documented

This is an in-progress draft. The content is incomplete and could change substantially.

This rule checks that custom keyboard commands are documented and that documentation is programmatically and visually available from any page/view to which they apply.

Applicability

This rule applies to any page/view in which an author has provided a custom keyboard command.

Expectation

The custom keyboard command is documented, and programmatically and visually available from any page/view to which it applies.

Examples

Shared assets

Several examples use the following Javascript.

keyboard-shortcuts.js

const actions = {
  focus: el => el.focus(),
  click: el => el.click()
};

function acceptsInput(element) {
  const selector = [
    "input",
    "textarea",
    "select",
    "[role='checkbox']",
    "[role='combobox']",
    "[role='option']",
    "[role='radio']",
    "[role='slider']",
    "[role='spinbutton']",
    "[role='textbox']",
    "[contenteditable]:not([contenteditable='false'])",
  ].join(", ");
  return element instanceof Element &&
    Boolean(element.closest(selector));
}

document.addEventListener("keydown", e => {
  if (e.metaKey || e.ctrlKey || e.altKey || e.repeat) return;
  if (acceptsInput(document.activeElement)) return;
  const target = document.querySelector(
    `[data-shortcut-key="${CSS.escape(e.key)}"]`
  );
  const action = actions[target?.dataset.shortcutBehavior];
  if (!action || !(target instanceof HTMLElement)) return;
  e.preventDefault();
  action(target);
});

Passed

Passed example 1

A search input can be focused using a custom keyboard command of / (forward slash). This custom keyboard command is documented as programmatically related description text for the input.

Open passed example 1 in new tab

<label for="search">Site search</label>
<input
  id="search"
  type="search"
  data-shortcut-key="/"
  data-shortcut-behavior="focus"
  aria-describedby="search-help"
/>
<small id="search-help">Keyboard shortcut: <kbd>/</kbd></small>
<script src="../../assets/keyboard-shortcuts.js"></script>

Passed example 2

A search input can be focused using a custom keyboard command of / (forward slash). This custom keyboard command is documented on a linked “Help” page.

Open passed example 2 in new tab

<p>
  <a href="help/">Help</a>
</p>
<p>
  <label for="search">Site search</label>
  <input
    id="search"
    type="search"
    data-shortcut-key="/"
    data-shortcut-behavior="focus"
  />
</p>
<script src="../../assets/keyboard-shortcuts.js"></script>
Linked help page
<p><a href="../">← Back</a></p>
<h1>Help</h1>
<h2>Keyboard shortcuts</h2>
<p><kbd>/</kbd> : Site search</p>

Passed example 3

A search input can be focused using a custom keyboard command of / (forward slash). This custom keyboard command is documented in a “Help” dialog on the same page.

Open passed example 3 in new tab

<p>
  <button type="button" commandfor="help" command="show-modal">Help</button>
</p>
<p>
  <label for="search">Site search</label>
  <input
    id="search"
    type="search"
    data-shortcut-key="/"
    data-shortcut-behavior="focus"
  />
</p>
<dialog id="help" closedby="any" aria-labelledby="help-heading">
  <div data-layout="stack">
    <h2 id="help-heading">Help</h2>
    <h3>Keyboard shortcuts</h3>
    <p><kbd>/</kbd> : Site search</p>
    <button commandfor="help" command="close">Close</button>
  </div>
</dialog>
<script src="../../assets/keyboard-shortcuts.js"></script>

Passed example 4

A search input can be focused using a custom keyboard command of / (forward slash). This custom keyboard command is documented in a “Help” dialog on the same page, which can be opened using a documented custom keyboard command of ? (question mark).

Open passed example 4 in new tab

<p>
  <button
    type="button"
    commandfor="help"
    command="show-modal"
    data-shortcut-key="?"
    data-shortcut-behavior="click"
  >
    Help <small><kbd>?</kbd></small>
  </button>
</p>
<p>
  <label for="search">Site search</label>
  <input
    id="search"
    type="search"
    data-shortcut-key="/"
    data-shortcut-behavior="focus"
  />
</p>
<dialog id="help" closedby="any" aria-labelledby="help-heading">
  <h2 id="help-heading">Help</h2>
  <h3>Keyboard shortcuts</h3>
  <p><kbd>/</kbd> : Site search</p>
  <button commandfor="help" command="close">Close</button>
</dialog>
<script src="../../assets/keyboard-shortcuts.js"></script>

Failed

Failed example 1

A search input can be focused using a custom keyboard command of / (forward slash). This custom keyboard command is not documented.

Open failed example 1 in new tab

<label for="search">Site search</label>
<input
  id="search"
  type="search"
  data-shortcut-key="/"
  data-shortcut-behavior="focus"
/>
<script src="../../assets/keyboard-shortcuts.js"></script>

Failed example 2

A search input can be focused using a custom keyboard command of / (forward slash). This custom keyboard command is visually documented but not programmatically determinable.

Open failed example 2 in new tab

<label for="search">Site search</label>
<div class="field">
  <input
    id="search"
    type="search"
    data-shortcut-key="/"
    data-shortcut-behavior="focus"
  />
</div>
<script src="../../assets/keyboard-shortcuts.js"></script>

The visible documentation is achieved using CSS techniques in which the conveyed meaning is not programmatically determinable:

.field {
  display: inline-flex;
  position: relative;

  input {
    padding-inline-start: 3.5ch;
  }

  &::after {
    content: '/';
    position: absolute;
    inset-inline-start: 0.5ch;
    inset-block-start: 50%;
    translate: 0 -50%;
    font-size: 0.75em;
    padding: 0 0.4em;
    color: #666;
    border: 1px solid currentColor;
    border-radius: 0.125em;
  }
}

Failed example 3

A search input can be focused using a custom keyboard command of s. This custom keyboard command is not documented. As a red herring, a custom keyboard command of / (forward slash) is documented, but does nothing.

Open failed example 3 in new tab

<label for="search">Site search</label>
<input
  id="search"
  type="search"
  data-shortcut-key="s"
  data-shortcut-behavior="focus"
  aria-describedby="search-help"
/>
<small id="search-help">Keyboard shortcut: <kbd>/</kbd></small>
<script src="../../assets/keyboard-shortcuts.js"></script>

Failed example 4

A search input can be focused using a custom keyboard command of / (forward slash). This custom keyboard command is documented with the input’s placeholder attribute, which is not reliably programmatically determinable.

Open failed example 4 in new tab

<label for="search">Site search</label>
<input
  id="search"
  type="search"
  data-shortcut-key="/"
  data-shortcut-behavior="focus"
  placeholder="Keyboard shortcut: /"
/>
<script src="../../assets/keyboard-shortcuts.js"></script>

Inapplicable

Inapplicable example 1

A button reveals a tooltip of “Press Space to activate” on focus and hover. The documentation is not necessary since it is describing a standard platform keyboard command.

Open inapplicable example 1 in new tab

<button type="button" aria-describedby="send-help">
  Send message
  <small id="send-help" aria-hidden="true">
    (Press <kbd>Space</kbd> to submit)
  </small>
</button>