Skip to content

Container roles need their required child roles

  • Rule: axe/aria-required-children
  • Checks: Certain ARIA roles must contain particular children
  • WCAG: 1.3.1
  • Fix class: mechanical: A fix needs no authored text or visual decision.
  • People who use a screen reader or a braille display, most of them blind.

Elements with roles of their own sit between the container and its items, such as the <li> elements of a <ul role="tablist">

Section titled “Elements with roles of their own sit between the container and its items, such as the <li> elements of a <ul role="tablist">”

Give each wrapper role="none" so it drops out of the structure, or remove the wrapper. A <div> or <span> with no role, focus or ARIA attributes is ignored already.

<ul role="tablist" aria-label="Plans">
<li role="none"><button type="button" role="tab" id="tab-monthly" aria-selected="true" aria-controls="panel-monthly">Monthly</button></li>
<li role="none"><button type="button" role="tab" id="tab-yearly" aria-selected="false" aria-controls="panel-yearly" tabindex="-1">Yearly</button></li>
</ul>
<div role="tabpanel" id="panel-monthly" aria-labelledby="tab-monthly"><p>$12 a month.</p></div>
<div role="tabpanel" id="panel-yearly" aria-labelledby="tab-yearly" hidden><p>$120 a year.</p></div>

The container holds other controls beside its items, such as previous and next buttons inside a tablist

Section titled “The container holds other controls beside its items, such as previous and next buttons inside a tablist”

Move those controls out of the container and place them beside it. A tablist, listbox, menu or tree may hold only its own item roles, plus the few the role allows, such as group in a listbox.

The items have no role, such as plain <div> children of role="list"

Section titled “The items have no role, such as plain <div> children of role="list"”

Give each item the role its container needs (listitem, option, tab, row, treeitem), or better, use native elements: <ul> with <li>, <table> with <tr>.

A list, table, grid, listbox, menu, tablist or tree is empty, so axe asks for review

Section titled “A list, table, grid, listbox, menu, tablist or tree is empty, so axe asks for review”

Check whether it is waiting for content. Set aria-busy="true" while items load and remove it once they arrive. Hide a container that stays empty, such as a listbox with no matches, and report “No results” in a status message; text alone inside the container fails the rule.

axe excuses missing children while the container is busy, but assistive technology may treat a busy element’s content as not ready, so the attribute must come off once loading ends.

Removing the container’s role to silence the rule

Section titled “Removing the container’s role to silence the rule”

The rule stops matching, but screen reader users lose the structure they rely on to count the items and move between them.

The part of the fix that differs in React, in its syntax. The rest of the guidance holds.

An item component renders a wrapper around the element that has the item role

Section titled “An item component renders a wrapper around the element that has the item role”

Make the element with the item role the outermost element the component renders, with its handlers and props on it. A Fragment adds no element, and a wrapper with only role="none", or a group the container allows, is also fine; a wrapper with another role, a tabIndex or a global ARIA attribute breaks the structure.

function Option({ selected, children, ...props }) {
return (
<li role="option" aria-selected={selected} {...props}>
{children}
</li>
);
}
function FruitList() {
return (
<ul role="listbox" aria-label="Fruit" tabIndex={0}>
<Option selected>Apple</Option>
<Option selected={false}>Pear</Option>
</ul>
);
}

The container renders a loading or “no results” message inside itself when it has no items

Section titled “The container renders a loading or “no results” message inside itself when it has no items”

Render the message beside the container, in a status region, and set aria-busy={loading} on the container while items load.

axe-core’s documentation of the rule

CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.