ARIA Roles
What are ARIA Roles?
ARIA roles are attributes that expose the purpose or type of an element to assistive technologies (e.g. screen readers). They don’t change how the element looks or behaves in the browser; they add or clarify semantics when native HTML isn’t sufficient (e.g. custom widgets).
Use it when: you’re building a custom interactive component (tabs, dialog, menu) or a non-semantic element that needs to be announced and operated correctly by assistive technologies.
Copy/paste template
- Element: [e.g. custom tab list, modal, combobox]
- Native first: [can we use
<button>,<nav>,<dialog>etc.? If yes, use that.] - If custom: [role + required attributes, e.g. role="tab" + aria-selected, aria-controls]
- Keyboard: [focusable, Enter/Space/arrows as per pattern]
- Test: [keyboard + one screen reader]
Why ARIA Roles matter
- Make custom UI understandable and operable for screen reader and keyboard users.
- Fill gaps when semantic HTML doesn’t exist for your widget (e.g. tabs, accordions).
- Support compliance with accessibility standards such as WCAG.
- Prevent confusion (e.g. a div that looks like a button but isn’t announced as one).
What good ARIA use includes
Checklist
- [ ] HTML first: use native elements (
<button>,<nav>,<main>,<dialog>, etc.) when they provide the semantics and behaviour you need. - [ ] Role matches behaviour: if you use role="button", the element must be focusable and respond to Enter and Space.
- [ ] Required attributes for that role (e.g. aria-selected, aria-controls for tabs; aria-expanded for expandable sections).
- [ ] Accessible name: every interactive element has a name (content, aria-label, or aria-labelledby).
- [ ] States updated: when the UI changes (e.g. tab selected, modal open), ARIA state attributes are updated in code.
Common formats
- Landmarks: role="banner", "navigation", "main", "complementary", "contentinfo" (prefer
<header>,<nav>,<main>,<aside>,<footer>when possible). - Widgets: role="button", "tab", "tablist", "tabpanel", "dialog", "menu", "menuitem", "checkbox" (with matching behaviour and attributes).
Examples
Example (the realistic one)
A team builds a custom tab panel. They use <div role="tablist">, <button role="tab"> (with aria-selected, aria-controls), and <div role="tabpanel"> (with aria-labelledby). On tab click, they update aria-selected and visibility, move focus to the active tab, and ensure only one panel is visible. They test with keyboard (Tab, Enter, arrows) and a screen reader. Native <button> is used for the tab trigger so focus and activation work without extra script for that part.
Common pitfalls
- Redundant ARIA: e.g.
<button role="button">. → Do this instead: omit the role when the native element already has the right semantics. - Wrong or missing semantics: e.g.
<ul role="navigation">instead of<nav>and a list inside. → Do this instead: use the correct native element; only add ARIA when you truly have a custom widget. - Role without behaviour: role="button" but no keyboard support or focus. → Do this instead: implement focus and keyboard (Enter/Space) and any other behaviour the role implies.
- Static ARIA: e.g. aria-expanded always "false" even when open. → Do this instead: update state attributes in JavaScript when the UI state changes.
- Missing name: interactive element with no visible text, aria-label, or aria-labelledby. → Do this instead: ensure every focusable control has an accessible name.
ARIA Roles vs. related concepts
- ARIA roles vs semantic HTML: Semantic HTML (e.g.
<button>,<nav>) gives behaviour and semantics for free. ARIA adds or overrides semantics for assistive tech only; it doesn’t change behaviour. Use HTML first; add ARIA when necessary. - ARIA roles vs ARIA states/properties: Roles say what something is (e.g. tab, dialog); states and properties (e.g. aria-expanded, aria-label) describe state or relationships. Use them together for widgets.
Related terms
Next step
Prefer semantic HTML and only add ARIA when you need it for custom components. Test with keyboard and at least one screen reader. For patterns that use ARIA (tabs, modals, menus), see interface patterns and interaction patterns and ensure accessibility is part of your definition of done.