aria-prohibited-children

Container roles must not own a child with a disallowed role

automaticWCAG 1.3.1 (A)confidence: mediumseverity: moderaterobust

Checks that every accessible-tree-owned child of a container role (list, listbox, menu, menubar, radiogroup, rowgroup, table, grid, treegrid, tablist, tree, row) has one of that role's allowed owned roles.

Applies to. Applies to elements with an explicit, valid role that is one of the container roles with a documented "required owned elements" entry (the same REQUIRED_OWNED_ROLES table aria-required-children uses, see src/core/aria-helpers.js).

Expectation. Every accessible-tree-owned descendant of the container (after pruning role="none"/"presentation" elements and any "group"/ "rowgroup" wrapper, both always transparent for owned-element matching per WAI-ARIA, regardless of whether "group"/"rowgroup" is itself in the container's own required-owned-roles set) has a role from that same required-owned set. Nothing else is a structurally valid direct child of a composite/container role, where "allowed" is the container's required-owned roles plus the small ALLOWED_EXTRA_OWNED_ROLES set of roles it may own without being required to (a separator between menu items, a caption on a grid). A roleless wrapper is descended into to reach the items a component library buries inside it, but once one is found there the rest of that wrapper's subtree is the item's own content and is not judged against the container.

Examples

pass
<ul role="menubar">
<li role="menuitem">File</li>
<li role="menuitem">Edit</li>
</ul>

Both owned children are roles menubar's spec allows.

fail
<div role="table">
<div role="row"><div role="cell">x</div></div>
<div role="button">Not a valid table child</div>
</div>

role="table" only allows row (or rowgroup) children; the button is a disallowed owned child.

View source