UI Component


A UI component is a page element with which the user interacts: button, link, input field, menu, or tab system. When it's a native HTML element, the browser handles accessibility. When built in JavaScript, it's the developer's responsibility to reproduce that behavior with WAI-ARIA and keyboard management.


A native <button> is accessible from creation: screen readers announce it as a button, it receives focus, it responds to Enter and Space keys. A <div> with an onclick does none of that. The difference comes down to one word: semantics.

#Native vs custom: what you lose

Interactive HTML elements (<button>, <a>, <input>, <select>) come with built-in accessible behavior. The browser knows which ARIA role to assign them, how to make them focusable, and which keyboard keys trigger them.

When you build a custom component in JavaScript, you start from scratch. The browser won't guess that your <div> is a button. A <div> transformed into a button must receive:

<!-- The minimum for a custom button -->
<div role="button" tabindex="0"
     onclick="action()"
     onkeydown="if(event.key==='Enter'||event.key===' ')action()">
  Submit
</div>
 
<!-- Or simply -->
<button onclick="action()">Submit</button>

The RGAA glossary summarizes the concept: a UI component is an element with which the user can interact. Link, button, input field, but also menu, dialog window, tab system.

#When the component goes beyond a simple button

A custom button is manageable. A tab system, a dropdown menu, a modal—that's another story.

For a tab system, the WAI-ARIA Authoring Practices Guide requires the tablist, tab, and tabpanel roles, the aria-selected and aria-controls attributes, and arrow key navigation between tabs. Miss even one of these elements and the component becomes opaque to a screen reader.

<div role="tablist">
  <button role="tab" aria-selected="true"
          aria-controls="panel-1">Tab 1</button>
  <button role="tab" aria-selected="false"
          aria-controls="panel-2" tabindex="-1">Tab 2</button>
</div>
<div role="tabpanel" id="panel-1">Content of the first tab.</div>

The same principle applies to menus (role="menu"), modals (role="dialog"), or accordions. Each pattern has its roles, states, and documented keyboard shortcuts. AcceDe Web publishes these patterns in French with reference implementations.

#The most costly mistake

Adding role="button" and forgetting the keyboard. The ARIA role only provides the label; it provides no behavior. A screen reader will announce "button," the user will press Enter, and nothing will happen. The MDN documentation says it clearly: role="button" without keyboard handling is worse than no role at all.

#In summary

Use native HTML elements whenever possible. If you build a custom component, follow the W3C APG design patterns: role, states, properties, and keyboard interactions. Test with the keyboard and a screen reader before declaring the component finished. An ARIA role without the associated behavior is an unfulfilled promise.

Share this article

Learn more