Accessibility: children presentational true element nesting another control injected via JavaScript #161
Description
Nested button elements are exposed inconsistently across browsers, whether implemented using HTML+JS or managed with ARIA alone.
Example: https://codepen.io/Giacomo-Petri/pen/bNbrWxz
ARIA version
<div role="button">
<span>outer button</span>
<span role="button">Inner button</span>
</div>
HTML + JS version
<div id="button-container">
<button id="outer-button">
<span>outer button</span>
<span id="inner-button-container"></span>
</button>
</div>
<script>
const innerButton = document.createElement("button");
innerButton.textContent = " (inner button)";
document.getElementById("inner-button-container").appendChild(innerButton);
</script>
ARIA version and HTML+JS version behave inconsistently:
-
ARIA version: According to ARIA specs 7.1 Excluding Elements from the Accessibility Tree:
user agents SHOULD NOT include the following elements in the accessibility tree: ... Any descendants of elements that have the characteristic "Children Presentational: True" unless the descendant is not allowed to be presentational because it meets one of the conditions for exception described in Presentational Roles Conflict Resolution. However, the text content of any excluded descendants is included.
In this case, the inner button should be excluded because its ancestor has presentational children. The inner button doesn't fall under a roles conflict resolution exception. Although it has role="button", it is not focusable and thus is treated as presentational.
- Browsers:
- Chromium and Gecko expose the nested button role, but per specs the SHOULD NOT
- WebKit ignores the button role, as per specs.
- Browsers:
-
HTML version:
If an element is focusable, user agents MUST ignore the none/presentation role and expose the element with its implicit role, in order to ensure that the element is operable.
In this version, the nested button is focusable by default. Because it is focusable, it falls under the roles conflict resolution exception, and its role as a button is exposed.
- Browsers:
- Chromium and Gecko expose the button role, as per specs
- WebKit ignores the button role, but per roles conflict resolution rule in ARIA specs, it shouldn't.
- Browsers:
Note: ref ARIA issue #2406