Keyboard accessibility means that every interaction a mouse user can perform, a keyboard user can also perform — without requiring unreasonable keystrokes. The W3C ARIA Authoring Practices Guide (APG) documents the expected keyboard interaction patterns for common widget types. Deviating from these patterns creates confusion because keyboard users have learned to expect them.
The two focus models
The APG defines two focus management models. In the "tab to the widget, arrow keys within" model (composite widgets), Tab moves into the component and arrow keys navigate within it. This applies to menus, listboxes, radio groups, trees, and tab panels. In the "tab through all" model, Tab moves between every interactive element. Understanding which model applies to a given component determines how you manage focus and tabindex.
Dialog and modal focus management
When a modal dialog opens: move focus to the first focusable element inside the dialog (or the dialog itself if no element is immediately actionable). Trap focus within the dialog — Tab and Shift+Tab cycle through focusable elements inside it only. When the dialog closes, return focus to the element that triggered it. Failing to return focus after modal close is a very common defect that leaves keyboard users lost on the page.
Focus trap pattern (simplified)
function trapFocus(dialogEl) {
const focusable = dialogEl.querySelectorAll(
'a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const first = focusable[0];
const last = focusable[focusable.length - 1];
dialogEl.addEventListener('keydown', (e) => {
if (e.key !== 'Tab') return;
if (e.shiftKey) {
if (document.activeElement === first) { e.preventDefault(); last.focus(); }
} else {
if (document.activeElement === last) { e.preventDefault(); first.focus(); }
}
});
}Menu and menubar patterns
Navigation menus that expand on click (disclosure patterns) are different from ARIA menus (role="menu"). Most site navigation should use the disclosure button pattern — a <button> with aria-expanded that shows/hides a list of links — not role="menu". ARIA menus follow arrow key navigation and are appropriate for application command menus, not site navigation. Using role="menu" for site navigation imposes unexpected arrow-key behavior on users.
Skip links
A skip navigation link is the first focusable element on the page. It links to the main content landmark (<main id="main-content">), allowing keyboard users to bypass repeated navigation. It can be visually hidden by default and appear on focus. This satisfies WCAG 2.4.1 (Bypass Blocks). Without a skip link, keyboard users must Tab through every navigation item on every page load.