--- name: keyboard description: > Load this skill for every project containing interactive UI elements — buttons, links, modals, dropdowns, sliders, tabs, carousels, or any custom widget. Under no circumstances create an interactive component that cannot be fully operated by keyboard alone. Absolutely always ensure visible focus indicators, logical tab order, and no keyboard traps. Apply these rules to every interactive element without exception. --- # Keyboard Accessibility Skill > **Canonical source**: `examples/KEYBOARD_ACCESSIBILITY_BEST_PRACTICES.md` in `mgifford/ACCESSIBILITY.md` > This skill is derived from that file. When in doubt, the example is authoritative. Apply these rules to every interactive UI element and feature. --- ## Core Mandate All interactive functionality must be fully usable with a keyboard alone — no mouse or touch required, except where the underlying function genuinely depends on path-based movement. Keyboard access is not equivalent to pressing Tab through every control — native and composite widgets use different key conventions, and users must understand how to operate custom widgets. --- ## Severity Scale (this skill) | Level | Meaning | | --- | --- | | **Critical** | Blocks task completion entirely for keyboard and AT users | | **Serious** | Significantly impairs keyboard access; workaround unreasonable | | **Moderate** | Creates friction for keyboard users; workaround exists | | **Minor** | Best-practice gap; marginal keyboard impact | Do not assign severity from the rule alone — determine the actual effect on the task. Consider whether the defect prevents reaching, operating, or leaving a component; whether it blocks an essential task or only an optional feature; whether focus is lost or placed misleadingly; and whether a reasonable keyboard method remains available. --- ## Critical: No Keyboard Trap If focus can enter a component, users must be able to move focus away using Tab, Shift+Tab, arrow keys, or Escape (depending on the component). If leaving requires an unusual command, provide instructions before or within the component. **A keyboard trap with no exit is Critical.** Restricting focus temporarily is NOT a trap when it is a modal dialog with a standard/documented exit: focus moves in on open, Tab/Shift+Tab stay within it, a keyboard-operable control closes/completes it, and closing returns focus to the invoking control or another logical location. Test embedded editors, third-party widgets, iframes, media players, remote desktops, and canvas applications carefully — they commonly consume Tab or other keys and need an available, documented exit. --- ## Critical: All Interactive Elements Must Be Keyboard Reachable Every element that can be activated by mouse must be reachable and activatable by keyboard. **Use native elements** — they provide keyboard behaviour, focusability, semantics, states, and browser integration built in at zero extra cost: ```html About
Save
``` Adding `role="button"` and `tabindex="0"` does not add button behaviour by itself — a custom button must also implement Enter and Space activation, disabled state, focus styling, and the expected accessible name/state. Test the actual result, not merely whether a `keydown` handler exists. Mouse and touch handlers must not be the only way to operate a control. --- ## Critical: Expected Key Behaviours Deviating from expected widget key behaviour is **Critical** — it breaks the mental model AT users depend on. Do not override standard browser behaviour on native controls without a documented need. Follow the current [WAI-ARIA APG](https://www.w3.org/WAI/ARIA/apg/) for custom widgets (versioned independently of WCAG — APG patterns are design guidance, not WCAG requirements by themselves; always confirm the current version). | Control | Required keys | | --- | --- | | Button | `Enter`, `Space` | | Link | `Enter` | | Checkbox | `Space` to toggle | | Radio group | Arrow keys to move between options; `Space` to select | | `