WCAG 2.4.3 Focus Order: How to Create a Logical Keyboard Navigation Order
This article explains WCAG 2.4.3 Focus Order and gives practical steps to create a logical keyboard navigation sequence. It covers causes of failures, a step-by-step audit, fixes such as avoiding tabindex>0, modal focus management, and testing advice.
WCAG 2.4.3 Focus Order: why keyboard order must match meaning
WCAG 2.4.3 Focus Order requires that keyboard focus moves through interactive components in an order that preserves meaning and operability. A correct focus order lets people who use keyboards or assistive tech move through content predictably.
What the success criterion covers
The requirement applies to any component that can receive keyboard focus, such as links, buttons, form fields, widgets and programmatically focused elements. The order of focus must let users complete tasks and understand the page without relying on a pointer or visual layout alone.
How bad focus order looks and why it fails users
- Tab moves to a hidden control first because the DOM puts it earlier. That confuses screen reader users.
- Visual layout is left-to-right but DOM order is different because CSS order or absolute positioning is used. Keyboard users get a different sequence than sighted mouse users.
- A modal opens and focus lands nowhere or lands on a background control. Keyboard users cannot interact with the modal.
Common technical causes
- DOM order does not match visual order because of CSS grid, flexbox order, floats or position absolute.
- Interactive elements added or moved by JavaScript without updating focus management.
- Use of tabindex values greater than zero to force an order.
- Elements hidden visually but left focusable or vice versa, often via aria-hidden or display:none misuse.
Quick testing checklist (manual)
- Switch off the mouse. Use Tab and Shift+Tab to move through controls.
- Confirm the order matches the visual order and task flow.
- Open all interactive widgets. Check focus when dialogs open and close.
- Use a screen reader like NVDA or VoiceOver with keyboard navigation to hear the reading order.
Automated and developer tools to help
- Browser DevTools / Accessibility tree to inspect DOM order and focusable elements.
- axe-core or other linters to flag tabindex>0 and common issues.
- Accessibility inspectors to check whether elements are focusable but hidden.
Step-by-step: audit and fix focus order
- Inventory focusable elements. Use document.querySelectorAll(‘a, button, input, [tabindex]’) to map the current order.
- Compare DOM order to the visual layout and task flow. Note where they differ.
- Decide whether to change the DOM order or change focus management. Prefer changing the DOM order when visual order is the intended reading order.
- Remove tabindex values greater than zero. Replace with tabindex=“0” only when you need a custom element to be keyboard focusable. Use tabindex=“-1” for programmatic focus targets only.
- For dynamic content, set focus programmatically to the first meaningful element and ensure it is focusable (tabindex=“-1” then element.focus()).
- Test again with keyboard and screen reader. Repeat until the order feels natural and task flow is preserved.
Decision framework: change DOM order or manage focus?
Use this short guide to pick your fix.
- If the visual order is the natural reading order and you can change the HTML without breaking layout, change the DOM order.
- If the visual order is decorative or the DOM order must stay due to semantics, keep DOM order and implement clear focus management. That includes programmatic focus on widgets and proper ARIA roles.
- If CSS positioning changes the visual order (for example grid/flexbox order), prefer reordering the HTML rather than relying on CSS order to avoid a mismatch.
Why tabindex>0 is almost always wrong
Using tabindex values greater than zero creates a separate, hard-to-manage focus sequence. It breaks the natural DOM-based tab order and makes maintenance fragile. Remove tabindex>0 and use other techniques instead.
Good alternatives to tabindex>0
- Reorder elements in the DOM to match the visual and task order.
- Use tabindex=“0” to make a non-interactive element reachable when needed.
- For temporary programmatic focus, set tabindex=“-1” then call element.focus().
Practical examples
Poor focus order caused by visual reflow
Example problem: navigation visually appears left of content but lives after content in the DOM. Tab order will reach the content first, then the navigation. That confuses users.
Fix: reorder the DOM or move the navigation earlier in markup
When you move the navigation markup before the content, tab will follow the visual order. This is the simplest and most robust fix when layout allows it.
Modal dialog: correct focus management
When a modal opens, move focus into the modal and trap it there. On close, return focus to the element that opened the modal. Use tabindex=“-1” on the modal container if it is not naturally focusable, then call element.focus().
Example pattern (pseudo-HTML)
<button id=“open”>Open modal</button> <div id=“modal” role=“dialog” aria-modal=“true” tabindex=“-1” hidden> <button id=“close”>Close</button> <input> </div>
// on open: // document.getElementById(‘modal’).removeAttribute(‘hidden’); // document.getElementById(‘modal’).focus();
// on close: // document.getElementById(‘open’).focus();
Dynamic single-page apps and widgets
In SPAs you often inject and reorder elements. Each time you change the UI, consider focus. If new content needs immediate keyboard attention, move focus to the new element. If content is updated but should not interrupt, do not move focus.
Handling CSS order, grid and flexbox
CSS order can change the visual sequence without touching the DOM. That creates a mismatch between what sighted users see and what keyboard users experience. If the layout needs a different reading order, prefer changing the HTML or use CSS carefully and test keyboard order after every change.
Small checklist to ship with confidence
- Keyboard-only navigation follows a logical sequence for the main tasks.
- No tabindex values greater than zero remain.
- Modals and overlays move focus into them and trap focus until closed.
- Programmatic focus uses tabindex=“-1” when needed and focus is returned to the opener.
- Visible and DOM order match for primary content and controls.
- Automated tests and manual keyboard runs are part of the release checklist.
Where focus order overlaps other success criteria
Good focus order supports other WCAG points such as clear navigation and predictable behaviour. Focus order alone does not fix mislabeled controls or missing landmarks. Use role and aria attributes where semantics require them, not to work around bad DOM order.
Final practical tips
- Start with the DOM. Make the HTML represent the content order you want users to follow.
- Avoid tabindex>0. It creates maintenance debt and hidden bugs.
- Test with real users and assistive tech in addition to automated checks.
- Document any exceptions where focus management deviates from DOM order and why.
Following these steps will help you meet WCAG 2.4.3 Focus Order and make keyboard navigation reliable for all users.