In this post we’ll cover some information and challenges in creating an accessible autocomplete box. A good autocomplete box is accessible by default and will allow all users to navigate intuitively, either by keyboard or mouse. Many of you may have used an autocomplete box before and not even realized that the keyboard shortcuts intuitively used were also there to allow impaired users access to the same functionality.
A challenging task
Building an accessible autocomplete box for the chat was challenging, given our strict set of requirements.
First, components need to adhere to AA accessibility standards and most libraries really just don’t cut it on this front. We also found some libraries that have too many features that we won’t use. Largely, what many libraries lack is markup structure and correct use of keyboard navigation / focus management. Also, our first implementation of the accessible autocomplete needs to open when the ‘@’ symbol is typed. An autocomplete box that appends inline requires a specific semantic markup structure which we’ll cover later …
Second, our chat input is a textarea and the autocomplete needs to open and append inline to existing text within the textarea value without replacing the whole value. IE: Most autocomplete widgets replace “I’m a big string @ inline” with “@selectedsuggestion.” Instead of “I’m a big string @ inline” with “I’m a big string @selectedsuggestion inline.”
Our autocomplete requirements in a nut shell:
- Keyboard navigation
- Semantic markup and aria attributes
- Suggestions append to the input value inline instead of replace the whole input value
- No functionality bloat
We found sourcing this probably the most challenging item in this task, as it was quite hard to decipher the w3 specifications for our requirements. It ended up that the w3 examples are actually quite comprehensive but need to be studied carefully (see authoring practices article).
Below you see a basic combobox implementation from w3. We recommend to check role details in more detail on the w3 website, because they share very helpful explanations.
<div aria-label="Tag" role="combobox" aria-expanded="true" aria-owns="owned_listbox" aria-haspopup="listbox"> <input type="text" aria-autocomplete="list" aria-controls="owned_listbox" aria-activedescendant="selected_option"> </div> <ul role="listbox" id="owned_listbox"> <li role="option">Zebra</li> <li role="option" id="selected_option">Zoom</li> </ul>
So from the example you can see the container needs:
The option elements need:
The input needs:
- On role=“option” – Cycle through aria-selected with keyboard navigation
- On the options container – Toggle hidden state for suggestions listbox
- On the input/textarea element – To set the aria-activedesendent
What Keyboard navigation is used for
- Up / Down – Cycle through suggestions
- Tab and Shift + tab – Cycle through suggestions
- Escape – Close suggestions
- Enter – Choose suggestion and close box