scottish-government-design-system / design-system

Design System for the Scottish Government and other Scottish public sector bodies
https://designsystem.gov.scot
MIT License
29 stars 12 forks source link

[BUG][Accessibility] Autocomplete element has missing semantics #119

Open jamiegaskell opened 3 months ago

jamiegaskell commented 3 months ago

Description of the issue

The autocomplete (combobox) element has missing ARIA and semantics. This includes:

Input element

The listbox element

DOM, the input element is missing ARIA attributes

Listbox element

DOM, selected options are not determined using aria-selected

Steps to reproduce the issue

  1. Navigate onto the element and observe that information such as the expanded state and selected options are not announced
  2. Inspect the code and compare with examples from the ARIA authoring practices page

Expected behaviour

Although not finalised, the ARIA authoring practices provide a good working example. See Editable Combobox With List Autocomplete

Environment

jsutcliffe commented 3 months ago

This is a complex topic without a good 'official' suggestion from W3C. An autocomplete requesting results dynamically is a different scenario from the fixed list of options in the W3C example you link to.

role=combobox:

We do not use the combobox role on the input element because it is not supported on inputs of type "search". The same is true for aria-expanded. We actually did have those attributes on a previous iteration of the component but dropped them when we decided that using the correct input type was more important.

In testing, I found that the expanded/collapsed state of the suggestions list was not being announced consistently with when we used aria-expanded. Instead, I've settled for an aria-live region that tells the user that there are options available to choose from (e.g. "These are 4 options"). This has worked consistently across devices/browsers I have tested on.

aria-owns/aria-controls:

A previous accessibility audit instructed us to use aria-owns on the input, but on reflection I agree that aria-controls seems more appropriate for this.

aria-selected:

We are using aria-activedescendant to flag the selected option. Setting aria-selected on the selected option was not getting announced reliably in screen readers, whereas aria-activedescendant behaves well in the testing I've carried out.

jamiegaskell commented 3 months ago

Hi @jsutcliffe,

Thanks for your feedback. From my experience, I think these kinds of components can be quite tricky to make accessible as there's no native way to build them. I think the most important thing is to keep it simple and make sure that everything is determined to assistive technology users to pass WCAG Name, Role, Value.

I've stumbled upon another example of an autocomplete/combobox on the GDS GitHub page - accessible autocomplete. They've used a combobox role and some of the attributes that I was thinking about. Would this not work in our case then? It's not published on the gov.uk design system however, so again I think it's experimental. There also seems to be a large number of open issues with it.

Interestingly they've not used aria-controls and have used aria-owns instead. According to MDN Web Docs: aria-controls, aria-controls is used to "identify the element (or elements) whose contents or presence are controlled by the element on which this attribute is set." They provide examples of combobox elements. The attribute aria-owns is used to “define a contextual relationship between a parent and its child elements when the DOM hierarchy cannot be used to represent the relationship (MDN Web Docs: aria-owns)”. I thought aria-controls would be more appropriate as the user is controlling something.

Another example of a search combobox is the one found on MDN Web Docs: Home page with the search field at the top of the page. This uses role="combobox" along with aria-controls. It might not be a perfect example, but I think in this case it's requesting results dynamically which might be more appropriate in our case. What do you think?

With using type="search", I feel that implies the component is more static, however the use of aria-haspopup="listbox" and the live region does suggest that the user has options to choose from. I just feel that using aria-expanded to determine pop ups is more explicit if it could be used. I believe combobox roles also have an implicit aria-haspopup value of "listbox".

That's interesting regarding aria-selected not working correctly, as it should be supported on elements with role="option" (source MDN Web Docs: aria-selected). It might be worth looking into.

Overall, I think the existing implementation does mostly work and users can bypass it anyway if they are struggling with it by hitting search. I'm just wondering if the component could be improved upon.

Has there been any feedback from user research on it?