Skip to content

Composite Roles — Tablist, Menubar, Grid and Combobox

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Composite Roles. We cover key concepts, practical examples, and best practices to help you master this topic.

ARIA composite roles like tablist, menubar, grid, and combobox contain and manage multiple child widgets with roving tabindex or aria-activedescendant for focus management.

In this tutorial, you'll learn how to implement composite widget roles in ARIA.

What You'll Learn

By the end of this lesson, you'll understand composite role patterns, roving tabindex vs aria-activedescendant, and how to implement combobox, menu, and grid patterns.

Why It Matters

Composite widgets are the building blocks of complex interfaces. Proper implementation means screen reader users can navigate menus, grids, and dropdowns efficiently.

Real-World Use

Doda Browser uses composite roles for its main menu bar, and Durga Antivirus Pro uses a grid role for the threat detection results table.

Composite Role Patterns

flowchart TD
  A[Composite Roles] --> B[tablist]
  A --> C[menubar / menu]
  A --> D[grid]
  A --> E[combobox]
  A --> F[listbox]
  B --> G[Contains tabs]
  C --> H[Contains menuitems]
  D --> I[Contains gridcells]
  E --> J[Input + listbox]

Tablist Pattern

The tablist manages a set of tabs with roving tabindex:

<div role="tablist" aria-label="Settings tabs">
  <button role="tab" aria-selected="true" aria-controls="panel-1" tabindex="0">General</button>
  <button role="tab" aria-selected="false" aria-controls="panel-2" tabindex="-1">Privacy</button>
  <button role="tab" aria-selected="false" aria-controls="panel-3" tabindex="-1">Security</button>
</div>
<div role="tabpanel" id="panel-1">...</div>
<div role="tabpanel" id="panel-2" hidden>...</div>
<div role="tabpanel" id="panel-3" hidden>...</div>

Arrow keys navigate between tabs. Only one tab has tabindex="0".

Combobox Pattern

The combobox combines a text input with a listbox for autocomplete:

<div role="combobox" aria-expanded="false" aria-haspopup="listbox">
  <input type="text" aria-controls="country-listbox" aria-autocomplete="list" />
  <ul role="listbox" id="country-listbox" hidden>
    <li role="option" id="us">United States</li>
    <li role="option" id="ca">Canada</li>
  </ul>
</div>
<div role="menubar" aria-label="File menu">
  <button role="menuitem" tabindex="0" aria-haspopup="true" aria-expanded="false">
    File
  </button>
  <button role="menuitem" tabindex="-1" aria-haspopup="true" aria-expanded="false">
    Edit
  </button>
</div>

Grid Pattern

A grid contains rows of cells with two-dimensional navigation:

<div role="grid" aria-label="Scan results">
  <div role="row">
    <div role="columnheader">File</div>
    <div role="columnheader">Status</div>
  </div>
  <div role="row">
    <div role="gridcell" tabindex="-1">document.pdf</div>
    <div role="gridcell" tabindex="-1">Clean</div>
  </div>
</div>

Common Mistakes

  • Using aria-activedescendant without managing the actual focus: The input element retains focus, but visual indicators must track the active descendant.
  • Missing aria-controls in combobox: The input must reference the listbox.
  • Not implementing arrow key navigation: Composite roles require keyboard navigation.
  • Forgetting to hide the listbox when not expanded: A collapsed combobox should have a hidden listbox.
  • Improper tabindex management in grids: Grids use roving tabindex per row or per cell depending on the pattern.

Practice and Challenge

1. What is the difference between roving tabindex and aria-activedescendant? Roving tabindex moves actual focus between elements. aria-activedescendant keeps focus on the container and indicates the active child virtually.

2. What composite role contains tab children? tablist.

3. What keyboard keys navigate a grid? Arrow keys move between cells. Tab enters and exits the grid.

4. What attribute does a combobox use to reference its listbox? aria-controls.

5. Challenge: Implement a combobox that filters a list of countries as the user types. Use the correct ARIA roles, aria-expanded, aria-autocomplete, and aria-activedescendant.

FAQ

What is roving tabindex?

A pattern where only one element in a group has tabindex='0', and others have tabindex='-1'. Arrow keys move focus and update tabindex values.

When should I use aria-activedescendant?

When the focused element is a text input or container, and the active child is indicated virtually.

Can a grid be used for data tables?

Yes. role='grid' is appropriate for interactive data tables with selectable cells.

What is the difference between menu and menubar?

A menubar is a persistent horizontal bar. A menu is a temporary dropdown.

Does a combobox need a text input?

Yes. Combobox requires an input element for text entry.

Mini Project

Build a combobox for selecting a protocol (HTTP, HTTPS, FTP, SFTP). Include keyboard navigation with arrow keys, filtering, and proper ARIA roles.

What's Next

Continue to Live Region Roles to learn about alert, log, marquee, status, and timer roles.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro