All Guides
Accessibility

Fix Keyboard Navigation

Make every interactive element work without a mouse.

What this covers: Make every interactive element work without a mouse, including the quick test, three common traps.

Who it’s for: Site owners and developers who need to meet accessibility standards and avoid legal risk.

Key outcome: You’ll have every interactive element (links, buttons, inputs, menus) is reachable via tab key in logical order, and focus indicator is clearly visible on every focused element (not suppressed by outline:none).

Time to read: 6 minutes

Part of: Accessibility series

Keyboard navigation is how people who can’t use a mouse get around your site—and yours is broken.

A user just emailed: “I can’t use your website with my keyboard.” You’ve never even tested that. You’ve never even thought about it. Tab, Enter, arrow keys—an entire way of using the web you’ve never considered.

Here’s what that email actually means: About 1 in 4 adults has a disability. Many can’t use a mouse—they rely on keyboards. Every day your site doesn’t work for them is customers walking away. And with ADA web accessibility lawsuits up 300% since 2018, “we didn’t know” isn’t a defense.

The Quick Test

Put your mouse aside. Navigate your site using only Tab, Enter, and arrow keys.

  • Can you reach every link and button?
  • Can you see where you are? (The focus indicator)
  • Can you submit forms?
  • Can you close popups?
  • Can you navigate menus?

If you got stuck, you found the problem.

Three Common Traps

1. Invisible Focus

You tab through elements but can’t see where you are. Your CSS probably has:

*:focus { outline: none; } /* Kills accessibility */

Fix: Remove it. Or use a visible style:

*:focus {
  outline: 2px solid #005fcc;
  outline-offset: 2px;
}

2. Fake Buttons

Something looks like a button but uses <div> instead of <button>. Keyboard users can’t reach it.

Fix: If it does something when clicked, make it a <button>. If it goes somewhere, make it an <a>.

3. Modal Escapes

A popup opens. You can’t escape. Tab cycles forever inside the modal, or worse—behind it.

Fix:

  • Escape closes the modal
  • Focus moves into the modal when it opens
  • Focus returns to the trigger when it closes
  • Tab stays inside the modal

Building a Proper Focus Trap

The modal focus trap is the hardest keyboard pattern to get right. Here is the correct implementation. When the modal opens: move focus to the first focusable element inside the modal (usually the close button or first form field). Trap Tab so it cycles only through elements inside the modal—when the user tabs past the last element, focus wraps to the first. When the user presses Escape or clicks the close button, close the modal and return focus to the element that triggered it. Without that return step, focus drops to the top of the page and the user loses their place.

Most JavaScript modal libraries (like A11yDialog or the native <dialog> element) handle this automatically. If you are building a custom modal, use inert on the background content to prevent focus from escaping. Never roll your own focus trap logic when tested libraries exist.

Tab Order Best Practices

Tab order should follow the visual reading order: left to right, top to bottom. If your tab order jumps erratically, the likely causes are: CSS positioning that changes visual order without changing DOM order, tabindex values greater than 0 (which override natural order and create chaos), or dynamically injected elements that appear at the end of the DOM but visually sit at the top of the page.

The fix: never use tabindex greater than 0. Use tabindex="0" to add an element to the natural tab order, and tabindex="-1" to make something focusable via JavaScript but not via Tab. Reorder your DOM to match visual layout. If CSS Grid or Flexbox reorders your content visually, the keyboard still follows DOM order—this disconnect is a common and serious accessibility bug.

The Skip Link

Keyboard users shouldn’t tab through your entire header to reach content. Add this:

<a href="#main-content" class="skip-link">Skip to main content</a>
<main id="main-content">...</main>

Hide it until focused:

.skip-link { position: absolute; left: -9999px; }
.skip-link:focus { position: static; }

Testing Tools

Pick the tool that fits your workflow and budget.

  • WAVE – Browser extension, flags keyboard issues
  • Accessibility Insights – Has a Tab Stops feature
  • Your keyboard – The real test

The standard: 1 2.1 Level A, 2.1.1 – All functionality keyboard accessible.

Keyboard Navigation Checklist

  • You can Tab through all interactive elements
  • Focus indicator is visible on every focusable element
  • Skip links work to bypass navigation
  • Modals trap focus and can be closed with Escape

Sources

Keyboard Navigation Questions Answered

Why does keyboard navigation matter for accessibility?

Many users cannot use a mouse: people with motor disabilities, power users, screen reader users, and anyone with a temporary injury. If your site cannot be fully operated with a keyboard alone, you are excluding approximately 10-15% of potential users and failing WCAG 2.1 Level A.

How do I test keyboard navigation on my site?

Put your mouse aside and press Tab to move through every interactive element on the page. Verify you can see a visible focus indicator on each element, reach all links and buttons, operate menus and modals, and return to the main content. Shift+Tab should move backward.

What is a skip navigation link?

An invisible link at the top of each page that becomes visible on focus and lets keyboard users skip directly to the main content. Without it, users must Tab through every navigation link on every page. Add it as the first focusable element in your HTML.

Why does focus disappear on some elements?

Usually because CSS includes outline: none or outline: 0 without providing an alternative focus style. Never remove the default focus outline without replacing it with an equally visible custom focus indicator. Use :focus-visible for modern styling that only shows on keyboard navigation.

✓ Your Keyboard Navigation Is Fully Accessible When

  • Every interactive element (links, buttons, inputs, menus) is reachable via Tab key in logical order
  • Focus indicator is clearly visible on every focused element (not suppressed by outline:none)
  • Modal dialogs trap focus — Tab cycles within the modal and Escape closes it
  • Skip-to-content link is the first focusable element and jumps to the main content area
  • Dropdown menus open with Enter/Space and allow arrow key navigation between items

Test it: Unplug your mouse, navigate your entire site using only Tab, Shift+Tab, Enter, Escape, and arrow keys — every action a mouse user can do should be possible.