Closed LauRoxx closed 2 months ago
This is a combobox where the associated listbox is not added to the DOM until the combobox is opened (so not a case where it's hidden and still referenceable). As such our automated scans ding it as a "confirmed" violation that our combobox is missing aria-controls, however aria-controls is there when the combobox is opened.
'User agents SHOULD treat state and property attributes with a value of "" the same as they treat an absent attribute.' https://www.w3.org/TR/wai-aria/#state_property_processing
Moreover, the WAI-ARIA github has a long history of conversations regarding aria-controls
, with this being one of the last major comments
An element's visibility and presence in the DOM are not synonymous.
Something can be in the DOM and not be visible, as mcking65 noted. A relevant case is the listbox associated with a combobox. It's not visible until the user makes a gesture to pop it open. This is a relevant case since aria-controls points from the combobox to the listbox, even when the listbox is not displayed (hidden). That's fine since aria-controls references an element in the DOM. Thus, aria-controls should not be limited to elements that are visible.
On the other hand, it's an author error when aria-controls references a non-existent element. That's something that a validator or QA should catch and the author should fix. If the error is not fixed, there is no graceful recovery. You simply can't navigate to something that doesn't exist. Compare this to when an author provides a link via an ID that doesn't reference any element in the DOM, e.g., <a href="invalidID" ... > If a user clicks that link, they go nowhere. It's implicit in the concept of "ID reference" that it be valid. There is no problem with the ARIA spec in this regard; nothing needs to be changed.
LJWatson's demo hides the controlled object by not adding it to the DOM. Furthermore, the aria-controls attribute is not added until the controlled element is added to the DOM. The script synchronizes the presence of aria-controls and the controlled element. That's fine too.
The possibilities are:
- The controlled element is in the DOM but is hidden. Adding aria-controls to the controlling element is valid.
- The controlled element is not in the DOM. Wait until it is before adding aria-controls to the controlling element; that is, synchronize the presence/absence of the two.
- The controlled element is not in the DOM but there is an aria-controls attribute on the controlling element. This is an author error that should be fixed.
- Addendum: even if an author does not fix the error, browsers will not expose the controller-for/controlled-by relationship in the accessibility tree, because, well, there is nothing to expose. In constructing the accessibility tree, the browser will attempt to follow the (bogus) aria-controls reference, but will find nothing and will give up. The result is that there is no controller-for pointer in the accessible object. The end result is as if no aria-controls was present in the DOM. In particular, there is no pointer that could mislead a screen reader.
We reached out to our Level Access contact for clarification on this "confirmed" issue as it seems to be effectively a non-issue. While the browser accessibility tree is valid, they proactively mark it as a confirmed issue to anticipate any issues with assistive technologies that might primarily scan the initial state of the DOM and not pick up a dynamically added list. However, this has not been an issue with our audits when using assistive technologies and many ATs are moving away from utilizing aria-controls. More over the fix of adding an empty aria-controls
does not address the reason for this being flagged. As such we have decided to not follow the scanned recommendations and instead disregard this warning.
Issue
This INPUT (role=combobox) must have all of the following attributes: aria-controls | aria-expanded
Details
Best Practice
Ensure ARIA roles, states, and properties are valid
Applicable Accessibility Standards
Offending HTML
<input value="" role="combobox" spellcheck="false" autocapitalize="none" aria-expanded="false" aria-autocomplete="list" class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall MuiInputBase-inputAdornedEnd MuiAutocomplete-input MuiAutocomplete-inputFocused css-1r1wf8p" type="text" id=":r0:" autocomplete="off" aria-describedby=":r0:-helper-text" aria-invalid="false">
Components/Stories Affected