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
tabindexvalues to force order. - Making a
divclickable 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
tabindexvalues or visual reordering conflict with DOM order. Put content in task order and use only0or-1when 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 managedinertstate.
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.