Lesson · Beginner

Keyboard access and visible focus

Make interactive controls reachable, operable, ordered, and visibly focused without recreating native keyboard behavior.

Published
Last checked

Native controls carry behavior

Use links for navigation and buttons for actions. They enter the tab order and provide expected keyboard activation without extra code.

:focus-visible {
  outline: 3px solid #f08a24;
  outline-offset: 3px;
}

Never remove an outline unless you replace it with a focus indicator that is at least as visible across backgrounds.

Test the sequence

Start at the browser chrome and use Tab, Shift+Tab, Enter, Space, and arrow keys where the component pattern calls for them. Focus order should follow the reading and task order. Opening a dialog must move focus inside; closing it must return focus to the control that opened it.

Common mistakes

  • Adding positive tabindex values to force order.
  • Making a div clickable without its keyboard and semantic contract.
  • Hiding an offscreen menu while leaving its controls focusable.

How browsers actually behave

Links, buttons, inputs, and other native controls enter the sequential focus order when they are usable. The browser moves focus in DOM order unless CSS, positive tabindex, or scripting creates a different experience. Visual reordering with grid or flexbox does not necessarily change keyboard order, so a card that looks first may be reached last.

Enter activates links and buttons; Space activates buttons but normally scrolls the page on links. Arrow-key behavior belongs to particular composite patterns such as tabs, menus, and radio groups. A generic element with role="button" gains a name but not all button behavior. Prefer the native element instead of rebuilding activation, disabled state, focus, and form semantics.

Decisions and trade-offs

Use :focus-visible to avoid showing a focus ring for every pointer click while preserving it for keyboard navigation. Keep a :focus fallback if your browser support policy requires one. The indicator must remain visible against light, dark, image, hover, selected, and forced-color backgrounds.

Focus management is justified when an interaction creates a new context. A modal dialog should receive focus, contain it while open, and return it to the invoker when closed. A normal page update should usually preserve focus; moving it after every small change disorients people and interrupts typing.

Accessibility consequences

Keyboard access supports people using switch devices, speech input, screen readers, alternative keyboards, and temporary one-handed workflows. A visible focus indicator tells them where the next command will apply. Screen-reader focus and DOM focus are related but not identical, which is why the keyboard and screen reader both need direct testing.

Do not mark interactive content aria-hidden, place focus inside an inert subtree, or hide content visually while leaving its controls available. These mismatches create destinations a person can reach but cannot perceive.

Failure diagnosis and fixes

  • Focus appears to vanish. A reset removed outlines or the ring matches the background. Restore an explicit high-contrast indicator with an offset.
  • Tab order jumps around. Positive tabindex values or visual reordering conflict with DOM order. Put content in task order and use only 0 or -1 when deliberate focus control is required.
  • A menu closes but focus is lost. The trigger was removed or focus was not restored. Keep a stable invoker reference and return focus after close.
  • Keyboard users reach hidden controls. The collapsed surface is merely offscreen. Remove it from rendering, apply hidden, or use a correctly managed inert state.

Verify it

Reload, leave the pointer alone, and traverse the entire page in both directions. Record the focus sequence and compare it with the reading and task order. Operate every control with its expected key. Open and close menus and dialogs repeatedly, including with Escape. At 200% zoom and 320 CSS pixels, confirm focus never lands outside the visible viewport and no sticky layer obscures it. Finally, inspect forced-colors mode and reduced-motion mode so the indicator does not depend on a custom color or animation alone.

Exercise and next step

Put the mouse aside and complete the primary task on one page. Record every point where focus disappears, becomes trapped, or reaches hidden content. Repair one failure at a time, then repeat the entire sequence rather than testing only the changed control.

Include an interrupted task in the repeat pass: trigger a validation error, open and dismiss a temporary surface, and continue from the same control. Focus should return to a useful, visible place each time. A sequence that works only from a clean page load is not a dependable keyboard interaction.

Free template + launch checklist

Build a page you can check before launch

Start with one reviewed semantic HTML page, then work through the one-page checklist against your published URL.

Check your inbox and confirm before the download arrives. No account required. We do not track email opens. See the privacy notice.