Removing the focus outline with outline: none — one of the most common CSS resets — makes it impossible for keyboard-only users to know where they are on the page. This affects sighted keyboard users (power users, users with motor disabilities who cannot use a mouse) as well as those navigating by switch access or sequential navigation. WCAG 2.2 SC 2.4.7 (Focus Visible) requires a visible focus indicator; SC 2.4.11 (Focus Appearance, AA in 2.2) adds a minimum area and contrast requirement of 3:1. SC 2.4.3 (Focus Order) is violated when positive tabindex values reorder focus in ways that conflict with visual layout. Section 508 2018 Refresh 503.4 requires keyboard navigation support. An invisible focus state means a keyboard user literally cannot use the application — they click Tab repeatedly with no visible response.
High because invisible or illogical focus indicators prevent keyboard-only users from knowing their position on the page, making navigation functionally impossible.
Audit your global CSS for outline: none or outline: 0 — these are only acceptable when a visible replacement focus style is provided on the same selector. Add :focus-visible styles for keyboard users without affecting mouse users:
/* globals.css or tailwind base layer */
/* NEVER use this without a replacement */
/* * { outline: none; } */
/* Provide a clear, high-contrast focus ring */
*:focus-visible {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
/* Component-specific overrides */
.btn:focus-visible {
outline: 3px solid #0066cc;
outline-offset: 2px;
border-radius: 4px;
}
/* Tailwind users: add to tailwind.config.js or use ring utilities */
/* className="focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2" */
Do not use positive tabindex values to reorder elements — reorder the DOM instead. Use tabindex="0" to add non-semantic elements to tab order and tabindex="-1" for programmatic focus only.
ID: accessibility-basics.semantic-structure-aria.tab-order-focus
Severity: high
What to look for: Check the tab order by tabbing through interactive elements in the application. The order should follow logical reading order (left-to-right, top-to-bottom). Check that a focus outline is visible on all interactive elements. Look for outline: none in CSS without a replacement focus style, or very faint focus indicators.
Pass criteria: Tab order follows logical reading order across all pages. Focus indicator is visible and has adequate contrast (at least 3:1 ratio). Positive tabindex is not used to reorder elements.
Fail criteria: Tab order jumps unexpectedly, or focus outline is removed (outline: none) without a visible replacement, or focus indicator is too faint to see.
Skip (N/A) when: Never — tab order applies to all interactive pages.
Detail on fail: Describe the tab order issue. Example: "Tab order jumps from top navigation to footer, skipping main content. Focus outline has outline: none with no replacement style — users cannot see which element has focus."
Remediation: Ensure logical tab order and visible focus indicators:
/* Provide a clear focus style */
button:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/* Never use outline: none without a replacement */
button:focus-visible {
background-color: #f0f0f0;
border: 2px solid #0066cc;
}
Avoid positive tabindex values. Let the DOM order determine tab order:
{/* Good: DOM order is tab order */}
<button>First</button>
<button>Second</button>
{/* Avoid: tabindex breaks natural order */}
<button tabIndex={2}>First</button>
<button tabIndex={1}>Second</button>