Required child elements of an ARIA role are missing
aria/required-children-missing
- WCAG success criterion
- 4.1.2 (level A)
- Outcome class
- Automatic. An automated check that can report a confirmed violation.
- Area
- Accessibility, Technical Robustness
- Default severity
- medium
- axe-core rule
aria-required-children
Why we flag this
Assistive technologies cannot resolve the relationship between the widget's parts.
e.g. role="tablist" without corresponding role="tabpanel" elements.
What the rule checks
Scope. Elements in the accessibility tree with an explicit role that has required owned elements (tablist, list, listbox, menu, table, grid, tree, ...); native tables and lists without role get their structure from HTML.
Expectation. Fails when such a container owns elements with roles, but none of the required ones (a tablist owning buttons instead of tabs, a menu owning buttons). Owning a required element directly, through generic wrappers or via aria-owns passes; so does a container without any owned element, one marked aria-busy=true (loading) and one with aria-expanded=false. Native tables and lists are not judged here. Hidden subtrees are out of scope.
Source. WCAG 2.2 SC 1.3.1 and SC 4.1.2; WAI-ARIA 1.2 section 5.2.6 (Required Owned Elements); ACT bc4a75
Detection: shared; needs dom, ax_tree.
Failing example
The check reports a violation here. Corpus case iframe_widget_rules, element iframe#widget [frame] ul#tabs. The page may contain further findings for other rules.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Iframe widget rules corpus case</title>
</head>
<body>
<main>
<h1>Widgets inside a same-origin iframe (#715)</h1>
<!-- Like gov.cy and magyarorszag.hu: a consent/dialog widget rendered
in an iframe. The dialog has no name, the tablist is built from a
list, so its tabs sit in list items instead of the tablist. The
frame document has no main landmark, no h1 and no skip link on
purpose: those are page-level rules and must not be reported for
a frame. -->
<iframe id="widget" title="Consent widget" style="width:600px;height:400px;border:0"
srcdoc="<!DOCTYPE html><html lang="en"><head><title>Widget</title></head><body>
<div role="dialog" id="consent-dialog"><p>We use cookies.</p><button type="button">Accept</button></div>
<ul role="tablist" id="tabs"><li><a role="tab" href="#one" id="tab-one">One</a></li><li><a role="tab" href="#two" id="tab-two">Two</a></li></ul>
</body></html>"></iframe>
<!-- Hidden from assistive technology: not audited. -->
<iframe id="hidden-widget" title="Hidden widget" aria-hidden="true" style="width:300px;height:100px;border:0"
srcdoc="<!DOCTYPE html><html lang="en"><head><title>Hidden</title></head><body><div role="dialog" id="hidden-dialog"></div></body></html>"></iframe>
</main>
</body>
</html>Passing example
The check passes here and reports nothing. Corpus case value_widgets_native. The page may contain further findings for other rules.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Native value widgets corpus case</title>
</head>
<body>
<main>
<h1>Native range, number and date inputs</h1>
<!-- Native controls expose their value without aria-valuenow, and the
day/month/year fields of a date input are the browser's (#656). -->
<label for="volume">Volume</label>
<input id="volume" type="range" min="0" max="10">
<label for="zoom">Zoom</label>
<input id="zoom" type="range" role="slider" value="3" min="0" max="10">
<label for="qty">Quantity</label>
<input id="qty" type="number">
<label for="amount">Amount</label>
<input id="amount" type="number" value="4">
<input type="date" aria-label="Order date value">
<label for="time">Pickup time</label>
<input id="time" type="time">
<label for="month">Billing month</label>
<input id="month" type="month">
<label for="week">Calendar week</label>
<input id="week" type="week">
<label for="appointment">Appointment</label>
<input id="appointment" type="datetime-local">
<label for="disk">Disk usage</label>
<meter id="disk" value="0.6">60%</meter>
<hr>
<div role="slider" tabindex="0" aria-label="Custom with value"
aria-valuenow="5" aria-valuemin="0" aria-valuemax="10"></div>
<div role="slider" aria-label="Hidden custom slider" style="display:none"></div>
</main>
</body>
</html>This page is generated from the rule catalogue and the rule contracts; see therule overview for how the outcome classes are derived.