New May 26, 2026

Keyboard Accessibility and Custom Components: Why ARIA Widgets Aren’t Enough

Company/Startup Blogs All from Level Access View Keyboard Accessibility and Custom Components: Why ARIA Widgets Aren’t Enough on levelaccess.com

ARIA (Accessible Rich Internet Applications) communicates roles, states, and properties to assistive technologies—but it doesn’t provide keyboard interaction behavior. Custom components built with ARIA widgets still require manually implemented focus management, keyboard event handling (including Enter, Space, and arrow keys), and dynamic state updates to be keyboard accessible.

Many developers assume that adding ARIA widgets to a custom component makes it keyboard accessible. It doesn’t. ARIA tells assistive technologies what something is—its roles, states, and properties—but says nothing about how it should behave with keyboard input. Focus management, event handling, and state updates all still need to be implemented manually. Without them, custom components that seem accessible in markup can be completely unusable in practice for many people with disabilities.

Key insights

Keyboard accessibility: A critical gap for ARIA widgets

When accessibility issues arise in custom components, ARIA widgets are often the first tool developers turn to.

The WAI-ARIA specification defines a set of widget roles that describe what a custom control is—a button, menu, or tab, for example—and how it changes over time, even when no native HTML equivalent exists. In that sense, ARIA widgets are designed to bridge the semantic gap between custom interfaces and assistive technologies. But there’s a key aspect of accessibility that ARIA doesn’t handle: keyboard interaction.

This is a critical missing piece. Many people with disabilities rely on keyboards or alternative input devices to engage with the digital world. If any functionality requires a pointing device, the experience is essentially broken for these users. And missing or inconsistent support doesn’t just cause problems for people who navigate with the keyboard only—it also impacts users of screen readers, switch control, and voice access who depend on keyboard events to interact with content.

Because keyboard accessibility is vital to providing usable experiences for people with disabilities, the Web Content Accessibility Guidelines (WCAG) 2.1 Success Criterion 2.1.1 (Keyboard) requires that all functionality be operable through a keyboard interface, with limited exceptions for custom widgets or complex interactions.

The challenges of keyboard support for custom components

Keyboard accessibility is straightforward when you use native HTML elements. Buttons, links, inputs, and form controls come with built-in keyboard behavior, focus management, and activation patterns that work reliably across browsers and assistive technologies. Challenges arise when applications move beyond these basics.

Modern web apps increasingly rely on custom widgets and complex interactions—dropdown menus, autocomplete fields, tab panels, modal dialogs, and interactive data visualizations. These components are typically built from generic elements like div and span, with JavaScript layered on top to manage interaction and state. While this approach enables richer experiences, ensuring keyboard accessibility becomes considerably more complex.

Unlike native controls, custom widgets aren’t focusable by default, don’t respond to standard activation keys, and provide no built-in semantics to assistive technologies. Every aspect of keyboard interaction—focus order, key handling, state changes, and visual feedback—must be implemented explicitly. When any part of that model is incomplete, keyboard users encounter barriers.

Why ARIA widgets don’t solve for keyboard accessibility

ARIA can tell a screen reader that an element is a button. But it can’t make that element focusable, clickable with Enter or Space, or navigable with arrow keys. Those behaviors have to be implemented manually.

As a result, ARIA widgets frequently fail when developers assume that adding ARIA attributes alone will make a component accessible. Without explicit keyboard event handling, logical focus management, and dynamic ARIA state updates, custom widgets remain unusable for many people who rely on assistive technologies.

This gap is reflected in real-world data. The 2026 WebAIM Million Report found that pages using ARIA averaged 59.1 detectable accessibility issues, compared to 42 on pages without it. ARIA only improves accessibility when it’s paired with correct keyboard behavior and consistent state management—especially for complex, interactive components.

ARIA and voice access

Relying on ARIA widgets alone doesn’t just cause problems for keyboard users. It creates barriers for voice navigation users, too. Dragon Professional, for example, has significant limitations with ARIA—a custom button implemented as <a role=”button”> is announced and treated as a link, regardless of its intended behavior. Similarly, Windows Voice Access (which is built into Windows), and Apple Voice Control rely on the accessible name of an element, not its visual label, to interpret voice commands. When those two things don’t match, voice navigation breaks down.

WCAG Success Criterion 2.5.3 (Label in Name) addresses this issue by requiring that an element’s accessible name also contains its visible label text. If you want your custom components to work for voice navigation users, make sure accessible names always include visible label text.

Building keyboard‑accessible web apps: Tips for developers

Now that we’ve established why ARIA alone isn’t enough, let’s explore what it takes to build keyboard-accessible custom components.

When you use ARIA widgets to represent buttons, menus, dialogs, or other controls built from non-semantic elements, you’re also responsible for implementing focus management, keyboard behavior, and state updates yourself. The following best practices can help you improve keyboard accessibility for custom JavaScript-driven components.

Manage focus order and tab sequence explicitly

Keyboard accessibility relies on predictable focus behavior, which native HTML controls provide automatically—but custom components don’t. Native elements such as <button>, <a>, and form inputs are focusable by default and participate correctly in the tab order. Custom widgets built from div or span elements require explicit focus management to be usable with a keyboard.

In custom components, use tabindex=”0″ to make a non-native element focusable without disrupting the natural tab order. And avoid positive tabindex values. They override the document object model (DOM) order and frequently create confusing navigation paths. This is especially true in composite widgets like menus, tab panels, or toolbars, which use a different navigation model altogether—focus lands on the widget, with arrow keys handling navigation within it via roving tabindex or aria-activedescendant.

The overall tab order should follow DOM source order and match the visual layout of the page:

Importantly, skip navigation links should remain the first focusable element on the page, even in highly interactive applications. This way, keyboard users can bypass repeated navigation and reach the main content efficiently.

Always provide a visible focus indicator

Every element that can receive keyboard focus must provide a visible focus indicator, including custom controls, composite widgets, and dynamically generated UI elements.

When you build custom components, it’s tempting to remove the browser’s default focus outline for visual reasons. But removing it without a visible replacement violates WCAG Success Criterion 2.4.7 (Focus Visible) and leaves keyboard users with no way to track where they are—particularly problematic in dense, app-like interfaces.

Modern CSS provides :focus-visible, enabling focus indicators to appear during keyboard interaction only. This preserves accessibility without affecting pointer-based design. It’s especially useful for custom components that simulate native controls.

Focus visibility also depends on layout behavior. WCAG 2.2 SC 2.4.11 (Focus Not Obscured) requires that focused elements not be hidden behind sticky headers, modals, or overlays.

Common mitigations include:

Trap focus in modals and use live regions intentionally

Custom dialogs and overlays are among the most common sources of keyboard accessibility failures in modern web apps.

When a modal dialog opens:

Native <dialog> elements and the inert attribute are reliable solutions for managing background content and focus. Without these, users may tab into hidden content, lose focus context, or get trapped.

The same principle applies to live regions: containers that allow assistive technologies to announce dynamic content updates without requiring a focus change. How and when they’re introduced in the DOM matters just as much as how they’re used. They should exist in the DOM on page load for reliable support:

Overusing live regions or injecting them dynamically can overwhelm assistive technology users.

Implement full keyboard support on every custom control

Custom controls are where ARIA is most often assumed to solve accessibility, and where keyboard failures happen the most. Controls built from div or span elements aren’t focusable by default, don’t respond to Enter or Space, and don’t expose interaction behavior automatically. A click handler alone doesn’t make a control keyboard accessible.

To make a custom control fully usable:

Miss any of these steps, and a component that seems accessible in a markup review can still be completely unusable for keyboard and assistive technology users.

Common keyboard accessibility failure patterns in custom components

Most keyboard accessibility failures don’t come from native HTML elements. They arise when teams build custom widgets and complex interactions that replace native behavior with JavaScript-driven logic.

Common failure patterns include:

If you can spot these patterns early in your development process, you’ll prevent regressions and avoid the remediation backlog that builds up when accessibility is treated as an afterthought.

Testing keyboard accessibility

Because keyboard failures in custom components are rarely obvious from markup alone, continual testing is essential to ensure barriers don’t go undetected. Automated accessibility tools catch only a portion of keyboard-related failures, because many keyboard issues stem from missing event handling, broken focus order, or incomplete interaction models rather than static markup errors.

Manual testing is essential. Ideally, it’s performed by an expert, but you can perform a quick spot check by unplugging the mouse and trying to navigate using only the keyboard. Every interactive element should be reachable, clearly focused, and operable. Verify that:

For more reliable insight, supplement manual testing with screen reader testing—NVDA with Firefox, JAWS or NVDA with Chrome or Edge, and VoiceOver with Safari.

Keyboard testing reference table

Keyboard interactions for common UI elements
Interaction Keystrokes Notes
Navigate to interactive elements
  • Tab: navigate forward
  • Shift + Tab: navigate backward
Keyboard focus indicators must be present. Navigation order should be logical and intuitive.
Link Enter: activate the link
Button
  • Enter
  • Space
Ensure elements with role="button" can be activated with both keys.
Checkbox Space: check / uncheck Users can typically select zero, one, or multiple options.
Radio buttons
  • Space: select focused option
  • / or /: navigate options
  • Tab: leave group
Users can select only one option from a group.
Select (dropdown) menu
  • /: navigate options
  • Space: expand
  • Enter or Esc: select and collapse
Users can often type letters to jump to options.
Autocomplete
  • Type to filter
  • /: navigate
  • Enter: select
Dialog Esc: close Modal dialogs should trap focus. Non-modals close on blur. Focus should return to trigger on close.
Slider
  • / or /: adjust value
  • Home/End: min/max
Double sliders use Tab to switch handles. PageUp/PageDown may adjust in larger steps.
Menu bar
  • /: navigate options
  • Enter: open/select
  • /: move between menus/submenus
Menu bars differ from standard link navigation.
Tab panel
  • Tab: enter/exit
  • / or /: switch tabs
For dynamic application tabs. Link-style tabs behave differently.
Tree
  • /: navigate items
  • /: expand/collapse
Scroll
  • /: vertical scroll
  • /: horizontal scroll
  • Space / Shift + Space: page scroll
Space scrolls only when focus is not on an interactive control.

 

Beyond ARIA: Building for accessibility by default

ARIA must be paired with explicit keyboard interaction behavior, focus management, and dynamic state updates to work reliably across assistive technologies. When you treat keyboard support and device independent access as baseline requirements—not afterthoughts—and use ARIA widgets intentionally, you can build digital experiences that work for everyone.

Ready to make keyboard accessibility a consistent, scalable part of your development process? Explore the Accessibility Resolution Playbook to learn how to streamline accessibility across the product development life cycle (PDLC) and get started with our tools for developers.

The post Keyboard Accessibility and Custom Components: Why ARIA Widgets Aren’t Enough appeared first on Level Access.

Scroll to top