Stockio

Keyboard Navigation Testing: Fix Focus Order and Traps

Build a repeatable keyboard testing workflow that catches unreachable controls, confusing focus order, and keyboard traps before your next release.

By Noor Haddad

Accessibility Specialist ·

On this page

Keyboard access breaks most often between otherwise reasonable components: a toolbar reordered for mobile, a sticky footer covering the active button, or a menu that opens without a way to leave. Testing individual buttons is not enough. You need to follow complete tasks using only a keyboard and check that the visual sequence still makes sense.

Map the expected keyboard journey

Start with a realistic task, such as finding an invoice and downloading its receipt. Write down the expected stops before touching the interface. Include navigation, filters, results, pagination, and any confirmation panel. This turns keyboard navigation into an observable workflow rather than a vague promise that everything supports Tab.

Use the Flexbox Playground to reproduce suspicious layout ordering. Change direction and order properties while comparing the rendered layout with the source sequence. It is a layout experiment, not an accessibility scanner: its value is showing why visual placement can diverge from DOM order.

Keep the WAI keyboard guidance nearby when deciding whether an interaction really requires a pointing device. Drawing paths may have specific exceptions; opening a settings panel does not.

Establish native controls and a sensible sequence

Links navigate and buttons perform actions. Those native elements already participate in sequential focus and provide established activation behavior. A clickable paragraph does neither automatically. Replacing it with a button is usually simpler and more reliable than adding roles, key listeners, focus styles, and disabled behavior yourself.

Use Tab and Shift+Tab to move through ordinary controls. Arrow keys belong inside particular composite widgets, such as tab lists or menus, when their complete interaction model has been implemented. Do not make every navigation link arrow-key-only because the header looks like a toolbar.

<nav aria-label="Account">
<a href="/account/profile">Profile</a>
<a href="/account/billing">Billing</a>
</nav>
<button type="button">Download receipt</button>

Avoid positive tabindex values. They create a separate priority sequence that becomes fragile when another component is inserted. A value of zero puts a custom focusable element into normal order; minus one allows programmatic focus without creating an ordinary Tab stop. Neither value supplies button semantics or activation behavior.

Review the MDN tabindex reference before introducing exceptions. Most ordinary pages should need very few tabindex attributes at all.

Make the active location unmistakable

A usable sequence still fails when users cannot see where they are. Inspect every focusable control, including icon buttons, pagination links, embedded widgets, and controls shown only after expansion. Visible focus needs to remain recognizable against the actual surrounding colors, not merely against the design canvas.

:where(a, button, input, select, textarea):focus-visible {
outline: 3px solid #173b85;
outline-offset: 3px;
}
html {
scroll-padding-top: 6rem;
}

This is a starting point, not proof of conformance. Check whether the outline is clipped by overflow, merges into a dark panel, or disappears under an overlay. Use the contrast checker to evaluate candidate ring colors against neighboring surfaces, then verify the rendered result at browser zoom.

WCAG 2.2 distinguishes focus visibility from focus not obscured. At Level AA, authored content must not entirely hide the focused component. A practical implementation should aim higher: users should see the control and enough context to understand it. Test sticky banners both before and after scrolling, since their impact often changes during a task.

Find traps and manage transitions deliberately

A keyboard trap prevents users from leaving a component using the keyboard, unless a nonstandard exit method is communicated appropriately. Test third-party editors, maps, media players, and embedded payment fields carefully. Enter each component, operate it, and then try moving both forward and backward out of it.

Modal dialogs deliberately contain focus while open, but they also need a keyboard-operable dismissal route where dismissal is permitted. Closing should return users to a sensible location, usually the control that opened the dialog. If that control was removed, choose a stable replacement associated with the completed task.

Single-page navigation needs another explicit decision. After a route change, leaving focus on a now-detached navigation item can strand keyboard users. Move focus to an appropriate heading or main region after the destination is ready, without creating extra stops in ordinary navigation. Do not move focus on every background refresh.

Watch for focus loss after destructive actions. Deleting row four should not send the user unpredictably to the browser chrome. Prefer the next available row action, the preceding row when necessary, or a clearly labeled empty-state heading. Document the chosen rule so repeated components behave consistently.

Record failures as reproducible tasks

Run the journey once without a screen reader to isolate keyboard behavior. Then repeat important paths with the assistive technology combinations your product supports. Screen readers can change which keystrokes reach a widget, so passing a plain keyboard test is necessary but not sufficient.

For each failure, record the starting URL, viewport, browser, exact keys, expected location, and observed location. A report saying that the filter is inaccessible is difficult to verify. A report saying that pressing Tab after Apply reaches a hidden reset button gives the implementer an actionable reproduction.

Use this compact regression checklist when a component changes:

  • Reach every available action without a pointer.
  • Activate links with Enter and buttons with their native keys.
  • Move backward through the same sequence.
  • Open, operate, and leave temporary interfaces.
  • Repeat after zooming and changing viewport width.
  • Confirm focus remains visible after scrolling and validation.

Automated checks can flag some tabindex and semantic errors, but they cannot establish whether a sequence makes sense. The WAI keyboard testing tutorial provides a useful starting procedure. Keep findings with other accessibility work, and turn each fixed defect into a focused test rather than relying on memory during the next release.

Key takeaways

  • Follow complete tasks, not isolated controls, when checking keyboard access.
  • Keep source order meaningful and prefer native interactive elements.
  • Make focus visible and prevent sticky content from hiding active controls.
  • Define entry, exit, and restoration behavior for temporary interfaces.
  • Combine repeatable manual journeys with targeted automated regression checks.
Featured sponsor

Reach designers & developers at work

Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.

Become a sponsor

Keep reading

Related articles

More in Accessibility
Accessibility

Accessible Dropdown Menus: Use Disclosure Navigation

Build dropdown site navigation that works with keyboards, touch, and screen readers without imposing the complex behavior of an application menu.

Includes: Flexbox playgroundTheo OkaforTheo Okafor
HTML & CSS

10 Best Online Code Playgrounds Like CodePen

Compare ten browser-based places to write, test, and share code, from quick HTML experiments to full-stack demos, with practical advice for choosing the right workspace.

Includes: Flexbox playgroundJonah WeissJonah Weiss
Motion & Animation

10 Best JavaScript and CSS Animation Libraries

Compare ten web animation libraries for interface feedback, scrolling effects, and expressive motion. Find a practical match for your coding comfort, project size, and performance needs.

Includes: Flexbox playgroundAiko TanakaAiko Tanaka
UI Design

Search Bar and Filter UI Design for Catalogs

Create search and filter interfaces with clear scope, predictable application rules, useful result feedback and responsive layouts for catalogs and dashboards.

Includes: Flexbox playgroundMaya LindqvistMaya Lindqvist
JavaScript & Frameworks

Interactive Documentation: Why Live Code Demos Win

Design fast, accessible documentation demos that start with readable static examples, add focused controls, and measure whether readers complete real tasks.

Includes: Flexbox playgroundDaniel KimDaniel Kim
JavaScript & Frameworks

shadcn vs Radix vs Headless UI: UI Libraries Compared

Compare Radix, Shadcn, and Headless UI through ownership, accessibility, styling, and maintenance, then choose a practical foundation for your next interface.

Includes: Flexbox playgroundSofia MarchettiSofia Marchetti