-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Description
Reproduction
Using the Select documentation page at https://material.angular.io/components/select/overview and the Axe DevTools Chrome plugin https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US
Steps to reproduce:
- Scan the entire page with Axe DevTools (version 4.3.1) at https://material.angular.io/components/select/overview
Expected Behavior
No critical issues related to ARIA
Actual Behavior
12 instances of "Required ARIA attributes must be provided" one for each that does not use the native select.
Environment
- Angular: 12.2.4
- CDK/Material: 12.2.4
- Browser(s): Chrome
- Operating System (e.g. Windows, macOS, Ubuntu): macOS
I've been tracking Select (ie. Combobox) a11y issues since 11083 and a fix with PR-20082. I believe dequelabs/axe-core#2505 fixed the false positive issue in Axe Core happening after PR-20082.
HOWEVER, with Axe Core 4.3 and ARIA 1.2 there is an additional accessibility requirement related to definition of aria-controls on the select field. The ARIA 1.2 spec states:
Authors MUST set aria-controls on a combobox element to a value that refers to the combobox popup element.
So the fix would be to set aria-controls to the id of the listbox div's id (eg. mat-select-50-panel); resulting in:
<mat-select role="combobox"
aria-controls="mat-select-50-panel"
aria-autocomplete="none"
aria-haspopup="true"
class="mat-select ng-tns-c176-163 ng-tns-c155-162 mat-select-empty ng-star-inserted"
aria-labelledby="mat-form-field-label-83 mat-select-value-51"
id="mat-select-50"
tabindex="0"
aria-expanded="false"
aria-required="false"
aria-disabled="false"
aria-invalid="false">
...
</mat-select>
...
<div role="listbox"
tabindex="-1"
class="ng-tns-c176-163 ng-trigger ng-trigger-transformPanel mat-select-panel mat-primary"
id="mat-select-50-panel"
aria-multiselectable="false"
aria-labelledby="mat-form-field-label-83"
style="transform-origin: 50% 24px 0px; font-size: 16px; opacity: 1; min-width: calc(100% + 32px); transform: scaleY(1);">
...
</div>