Unplug your mouse. Open your internal ticketing tool and try to file a ticket. If you got past the landing page without hitting a dead end, you're doing better than most of the custom dashboards we audit.
Keyboard-only navigation is the single fastest accessibility signal you can check. It takes ten minutes, requires no tooling, and surfaces problems that automated scanners miss entirely. This is the audit we run first on every portal we touch.
Why Keyboard Nav Matters Beyond Screen Readers
Screen reader users rely on keyboards. That's the obvious case. The population that benefits is much wider:
- Users with motor impairments who can't use a precision pointing device
- Power users who navigate faster with Tab and shortcuts than with a mouse
- Users on laptops with broken trackpads or flaky Bluetooth mice
- Anyone using a remote desktop session over a lossy connection
- Automated testing tools and browser extensions that drive the DOM
When keyboard navigation breaks, it usually means the underlying focus management is broken, which cascades into screen reader issues, assistive switch issues, and voice-control issues. Fix the keyboard path and you fix most of them.
The 10-Minute Audit Protocol
Disconnect your mouse or sit on your hand. Open the app and run through this list. Don't skip steps. The failures stack.
Minute 1-2: Tab order. Start from the URL bar, Tab into the page, and Tab all the way through. Note the order. Does it match the visual layout? On a dashboard with a sidebar, header, and main content, Tab should reach header → sidebar → main content in roughly that order. If focus jumps to a hidden settings drawer on Tab #3, you have a problem.
Minute 3: Focus indicators. On every Tab press, ask: can I see where focus is? If the ring disappears on buttons, inputs, or card links, that's a failure. If it's a faint 1px outline against a busy background, also a failure.
Minute 4: Skip links. Reload the page and press Tab once. A "Skip to main content" link should appear. If there's no skip link on a dashboard with 40+ nav items, users have to Tab through all of them on every page load.
Minute 5-6: Modal traps. Open a modal (ticket detail, settings, confirm dialog). Tab through it. Focus must stay inside the modal until you dismiss it, and Escape must close it. If Tab leaks to elements behind the modal, or Escape does nothing, file it.
Minute 7-8: Hidden-but-focusable. This is the nastiest category. Tab through and watch for the focus ring disappearing for several presses in a row. That means Tab is landing on display: none-adjacent elements: off-screen menus, collapsed accordions, aria-hidden containers with focusable children. Users can't see where they are.
Minute 9-10: Custom controls. Try every custom widget: dropdowns, date pickers, combobox search, drag-and-drop lists. Can you open them with Enter or Space? Navigate with arrow keys? Close with Escape? Most custom components fail at least one of these.
The 4 Failure Patterns You'll Actually Hit
After auditing dozens of custom dashboards, the same four patterns account for the overwhelming majority of findings.
1. Divs pretending to be buttons. <div onClick={...}> is the most common failure we see. It's not focusable, it doesn't respond to Enter or Space, and screen readers don't announce it as interactive. Users can see it, click it with a mouse, and have no idea it exists otherwise.
2. Focus rings removed globally. Somewhere in the CSS is a *:focus { outline: none; } with no replacement. A designer didn't like the default blue ring and nobody put back a custom one. Now nobody knows where focus is, ever.
3. Modal focus leakage. The modal opens, but focus stays on the button that opened it. Or Tab eventually escapes to the background content. Or Escape does nothing. These are three separate bugs and most modals have at least one of them.
4. Hidden menus still in the tab order. A mobile nav menu is hidden at desktop widths via display: none, which is correct. But a "user profile" dropdown uses opacity: 0 and pointer-events: none, which leaves it focusable. Tab lands on invisible links for 8 keypresses before reaching anything visible.
The Tiny Fixes That Solve 80% of Them
Most keyboard accessibility bugs are cheap to fix. You don't need a library or a refactor.
Replace clickable divs with buttons.
<!-- Bad -->
<div class="card" onclick="openTicket()">...</div>
<!-- Good -->
<button type="button" class="card" onclick="openTicket()">...</button>
Use <button> for actions, <a> for navigation. Style them however you want. all: unset plus your own styles is fine.
Restore a visible focus indicator. If the design forbids the default browser ring, replace it with something equivalent:
*:focus-visible {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
:focus-visible only shows the ring on keyboard focus, not mouse clicks, which usually satisfies the design concern.
Add a skip link. One line of HTML and four lines of CSS:
<a href="#main" class="skip-link">Skip to main content</a>
.skip-link {
position: absolute;
left: -9999px;
}
.skip-link:focus {
left: 1rem;
top: 1rem;
}
Hide elements from the tab order when hiding them visually. Use display: none or visibility: hidden when you want something gone. If you need it in the DOM but not focusable, add inert to the container. It's supported in every current browser and removes the entire subtree from Tab order.
Run the 10-minute audit on your own portal this week. If you find more than a handful of failures and want help remediating at scale, schedule an accessibility audit and we'll take it from there.