About
Autocomplete is an amazing tool for your website. It helps your users find what they're looking for, much faster than they would if they typed everything and clicked the Search button.
For example, if I'm using a search engine for capital cities called "Capital Search" to search for "Nicosia", instead of typing the whole name and clicking Search, I can just type the first 2-3 letters ("nic") and the result will show up right under the text box. Now I can just click it and it will take me straight to the website!
Interactive page available on CodePen
However this instant interaction with your users comes with a small but important issue.
Quick overview of our autocomplete code
Before we explore the problem with autocomplete, let's explore how our code currently looks like. The full code is available here. The way it works is quite simple:
- The user types on the input field
- Every time they type, a list of capital cities is filtered to get a list of all capital cities starting with the user's input string. For example if I type "n", the cities of "Nassau", "Nicosia", "Nairobi" etc. get returned as search results.
- The results are shown as a list under the input box.
- Clicking on an item takes the user to the city's Wikipedia page.
The problem
The issue with autocomplete has to do with accessibility, specifically with screen reader software. Every time a user types on the input box, the state of the page changes: the results from autocomplete are updated and presented to your user.
However, the screen reader does not recognise this as an action to tell the user about. It will announce the header ("Capital Search") and the input box when they gain focus, but not the search results.
You, as the developer, will need to put something in place in order to tell the screen reader user how many results have been found while typing the search.
The solution: "Live regions"
The solution for this problem is what we call an "ARIA live region". We're basically using the aria-live
tag to create a <div>
. Whenever this tag is included, the screen reader will announce any change happening to its contents. It looks like this:
<div role="region" aria-live="polite">0 results found</div>
If the content changes to "2 results found", the screen reader will let the user know.
Updating our code
Now we need to update our code from the CodePen link above to include our live region.
First, let's add the region to our HTML:
<div id="page">
<div id="container">
<h1>Capital Search</h1>
<div id="search">
<div id="autocomplete">
<input type="text" id="query" onkeyup="respondToSearchboxChange()"/>
<ul id="results">
</ul>
</div>
</div>
</div>
</div>
+ <div id="live-region" role="region" aria-live="polite"></div>
Now we need to update our Javascript code to update our live region every time there's a change in search results:
function respondToSearchboxChange(){
var input = document.querySelector("#query").value
var searchResults = []
if(input.length > 0){
searchResults = capitals.filter((capital) => capital.toLowerCase().startsWith(input))
}
+
+ document.querySelector("#live-region").innerHTML = `${searchResults.length} results found`
document.querySelector("ul#results").innerHTML = searchResults.map((result) =>
`<li><a href="https://en.wikipedia.org/wiki/${result}" target="_blank" rel="noreferrer">${result}</a></li>`
).join("")
}
Finally, since we don't want the region to be visible on the page itself, we are going to hide it using CSS:
#live-region{
position: fixed;
top: -100px;
}
Full code available on CodePen
That's it! Your autocomplete is now ready and accessible to screen reader users. Every time the result count changes, the screen reader will let the user know. Awesome!
Let me know, either here or on Twitter, how you found this tutorial. Have it helped you make your autocomplete function more accessible?
Top comments (9)
Thanks Savvas nice one.
Why only include the count and not the results themselves in the live-region though ?
Thanks Giorgo! ๐
Very good question!
The reason I havenโt included the results themselves is because the search could potentially return 10-20 results or even more. If the screen reader reads every single result, it will overwhelm the user. So a much simpler โ2 results foundโ etc. is much better.
Thanks I got it
Perhaps one can include the results only if it is 1 or 2 to help further with accesibility.
Thatโs actually not a bad idea ๐๐
interesting... thanks for sharing this awesome knowledge. One question, how can I enable the reader to read the
<li />
s in the suggestions box (<ul />
)? Is this handled by the screen reader automatically?Hello Siddhant! Thank you for reading, I'm glad you found it useful.
The important thing here is to make sure the search results are available immediately after the input box. That is, the user can reach the search result list with a click of the tab button when the input box is in focus.
Interesting!!
๐
Awesome. Thank you for sharing