Autocomplete
A text field that suggests options while you type. Learn the combobox pattern, list vs inline completion, free text vs must-pick fields, and the timing, matching and keyboard bugs testers find in address and city pickers.
Type “Lon” in a travel app and London Heathrow appears. Type the first letters of your street at checkout and the full address is offered. Type “@gm” in an email field and “gmail.com” is filled in. That’s autocompleteAutocompleteSuggestions shown under a field while typing, which the user can pick to finish the input.Open in glossary →: a text field that guesses what you mean while you type.
It feels simple, but it’s a text field, a dropdown and a small search engine glued together, with a network request on every pause. Bugs hide in the glue: what’s typed vs what’s selected, which response arrives last, which keys do what. This page is about the autocomplete field. The search results page behind a search bar and the timing of search requests in general are covered in Search, filters & sorting.
What is autocomplete?
An autocomplete field is a text input that shows matching suggestions as you type, so you can pick one instead of typing it all. In code (on the web and in accessibility specs) it’s called a combobox: a combination of an editable box and a list of options.
There are two important questions for every autocomplete, and testers should know the answer before starting:
- Must the user pick from the list, or is free text allowed? A city for delivery, an airport, a country or a product variant must be one of the options (it has an id behind it). A search query, a tag or a town that might not be in the list can be anything.
- Where do suggestions come from? A local list (200 countries, built into the app) is instant. A server search (millions of addresses) is slow, can fail, and answers in an unpredictable order.
Anatomy
City1
🔊 “4 results available”7
- 1
Label
Says what to type ("City"). Visible and connected to the input, like any text field.
- 2
Input (the combobox)
What the user typed. Its text is not the value yet: the value is set when an option is chosen.
- 3
Clear button
Empties the field and the selection. Needs a name ("Clear city") and a 44 pt / 48 dp touch area.
- 4
Suggestion list (listbox)
Opens below the field after enough characters. Must close on Esc, on selection and when focus leaves.
- 5
Active option
Moved with the arrow keys, chosen with Enter. Clearly visible, and different from "selected".
- 6
Matched part
The part of each option that matches the query, in bold. Must match the same way as the search (case, accents).
- 7
Result count (status)
Invisible on screen but announced: "4 results available". Also says "No results".
List, inline, or both
| Style | What happens | Typical use |
|---|---|---|
| List | A list of matching options opens under the field | Cities, addresses, products, people |
| Inline | The rest of the word is filled in and selected; typing on replaces it | Browser address bar, email domains |
| List + inline | The list opens and the first match is also completed in the field | Some address bars and code editors |
Dev note
aria-autocomplete="list", "inline" and "both". You’ll see these values in DevToolsDevToolsDeveloper tools built into browsers for inspecting pages, network traffic and errors.Open in glossary → when you inspect the field.How it differs from similar components
| Component | You type… | You get… |
|---|---|---|
| Autocomplete / combo box | Part of a name | Suggestions; one becomes the value (or free text) |
| Dropdown / select | Nothing (or one letter to jump) | One option from a fixed list |
| Search bar | A query | A results page; suggestions are only shortcuts |
| Chips / token field | Part of a name, many times | Several selected values shown as chips |
| Browser autofill | Nothing | Saved personal data filled into a form (see Text field) |
Designs & variants
Every field here works. Type a few letters (try nis, sabac or novi), use the arrow keys, Enter and Esc, then click outside.
Form value: null
List autocomplete, must pick
WebA combobox: type to filter, choose with arrows + Enter or a click. Leave the field with text that isn't a city and you get an error, not a silently invalid address.
Form value: null
Exposed dropdown menu
Android · Material 3Material's text field with a filtered menu (AutoCompleteTextView / ExposedDropdownMenuBox). Same rules: arrows, Enter, Esc, and the menu closes when focus leaves.
- Nova Pazova22330, Serbia
- Nova Varoš31320, Serbia
- Novi Bečej21220, Serbia
- Novi Kneževac23330, Serbia
Full-screen search
iOSOn phones, apps often move the field to the top and show results as a full list above the keyboard. A small floating list would be hidden behind the keyboard.
Type anna@g. Press → or Tab to accept, keep typing to overrule, Backspace to drop the suggestion.
Inline completion
WebThe rest of the text is filled in and selected: the browser address bar and email-domain helpers work like this. Typing on replaces the suggestion; deleting must not bring it back.
Form value: null
Suggestions + free text
WebWhen the list can't know every answer (small villages, new streets), the first row keeps exactly what the user typed. Then the form must accept a value without an id.
How a good autocomplete behaves
It waits for enough input. One letter matches half the list and wastes a server call. Most fields start after 2–3 characters (local lists can start at 1) and say so: “Type at least 2 letters”.
It waits for a pause, and ignores old answers. Requests are sent after a short debounceDebounceWaiting until the user stops typing for a moment before reacting, for example before searching.Open in glossary → (around 200–300 ms). Responses can arrive in any order, so the app must only show the answer to the latest query. Otherwise the slow answer for “no” overwrites the fast answer for “novi”: a race conditionRace conditionA bug that depends on the timing or order of events, so it only happens sometimes.Open in glossary →. The Search, filters & sorting page shows this with a live demo.
It matches the way people type. Case and accents are ignored (diacriticsDiacriticsAccent marks on letters, like é, ü, č or ž. Search usually should ignore them.Open in glossary →: “sabac” finds Šabac), and words in the middle count (“sad” finds Novi Sad). The Dropdown page has a matching lab for this.
It highlights the matched part, using the same matching rules. If the search ignores accents but the highlighting doesn’t, users see options with nothing bold and wonder why they’re there.
It shows the empty and the loading state. “No cities match ‘nobi’. Check the spelling.” is an empty stateEmpty stateThe screen a user sees when there is no content yet, like an empty cart or no search results.Open in glossary →; a spinner or “Searching…” covers slow networks. Silence (no list at all) looks like a broken field.
It keeps typed text and selected value apart. The text in the field is just text until the user chooses an option. If they edit the text afterwards, the selection must be cleared. And if they leave the field without choosing, a must-pick field shows an error (or accepts an exact match), but never saves “novi” as a city.
It obeys the keyboard. Arrows move through the options, Enter chooses, Esc closes the list (a second Esc may clear the field), Tab moves on. More in Accessibility.
It closes when it should: after choosing, on Esc, when focus leaves the field, and when the user taps outside.
When to use it
Autocomplete is a good choice when:
- The list is long (cities, airports, addresses, medicines, products), too long to scroll in a dropdown.
- Users know what they want and can type the first letters.
- Typing it fully is error-prone: long names, accents, exact spellings needed for delivery.
- You want to suggest but still allow free text (search queries, tags, small towns).
Good and bad uses
Short list: just show it
Delivery time
Three options, all visible, one tap.
Typing to find one of three
Delivery time
Type what? Users have to guess the options before they can see them.
Must pick: show what was chosen
City
✓ Postcode filled in
The chosen option fills related fields, so it’s obvious a real city was picked.
Must pick, but free text slips through
City
Postcode: (empty) · Continue ›
“novi” isn’t a city. The order is saved anyway and the courier can’t find the address.
Also skip autocomplete when users need to compare options (show a list with details), and be careful with it for sensitive data: suggestions based on other users’ searches can leak private information.
Common bugs
| # | Bug | What you see | Typical severity |
|---|---|---|---|
| 1 | Typed text saved, nothing chosen | “novi” is saved as the city; no postcode, no id | High |
| 2 | Stale results | The list shows results for an older query | Medium–High |
| 3 | No keyboard support | Arrows do nothing; Enter submits the form | High (for affected users) |
| 4 | Esc clears the field | Instead of closing the list, Esc wipes what you typed | Medium |
| 5 | List won’t close | It stays open after Tab or a tap outside and covers the form | Medium |
| 6 | Edited after choosing | Change “Novi Sad” to “Novi Pazar” by typing: the old id is still sent | High |
| 7 | Accents and case | “sabac” finds nothing, or finds Šabac but highlights nothing | Medium |
| 8 | No empty or loading state | Nothing appears, so users think the field is broken | Medium |
| 9 | Request on every keystroke | Ten requests for ten letters; flicker and rate limits | Medium |
| 10 | Hidden by the keyboard | On a phone, the list opens behind the on-screen keyboard | High |
| 11 | Silent for screen readers | No result count, options not announced | High (for affected users) |
| 12 | Special characters | &, ' or % break the request (“O’Hare”, “Ivo & Co”) | Medium |
Stress-test it
Timing and matching are where autocomplete breaks. This lab answers short queries slowly, like a real server searching more rows. Use the auto-type buttons to type fast, then change one setting at a time.
🧪 Autocomplete lab
Short queries answer slowly here (like a real server searching more rows). Use the auto-type buttons to type fast, then change the settings and type again.
Debounce and late responses only matter while typing: use the auto-type buttons.
- Šabac15000
- Novi Sad21000
Field text / form value
“sa” · no city selected
Screen reader hears
“2 results available.”
Requests · 0 keystrokes, 0 requests
- Type or use an auto-type button…
Naive highlighting compares raw letters, so options found through accents (Šabac for "sa", Niš for "nis") get no bold part, or the wrong one.
Nothing is selected yet. If the user leaves the field now, the form must not treat the typed text as a valid city.
Find the bug
FreshBasket’s checkout asks for a delivery address. The City field is an autocomplete with six bugs. Explore it like a real tester:
- Type a city quickly (e.g.
novi) and watch the list and the network log. - Type a city without accents (
sabac,cacak) and with one the city doesn’t have (nóvi). Look at the bold part. - Use only the keyboard: arrows, Enter, Esc, Tab.
- Click or Tab away while the list is open.
- Type part of a city and press Continue to payment without choosing.
🐞 Bug hunt: FreshBasket delivery address
This demo has 6 hidden bugs. Explore it like a tester, then check your findings.
FreshBasketCheckout · 1 of 3
- Type a city to see requests…
- 1
Hint: Type "novi", don't pick anything, and press Continue to payment. Read the network log.
- 2
Hint: Type "kra" and press the Down arrow, then Enter.
- 3
Hint: Type "novi" quickly (or paste "no" and then type "vi"). Compare the list with the field and the order of responses in the log.
- 4
Hint: Type "subo" so the list opens, then press Esc.
- 5
Hint: Type "kr", then click the Full name field or press Tab.
- 6
Hint: Type "sabac" and "cacak", then "nóvi". Then type "kra" and compare.
How to test it
Checklist
Autocomplete test checklist
0 of 14 checked
Example test cases
TC-AC-001Choose a city with the keyboardpositivehigh
Steps
- Tab to City
- Type "kra"
- Press Down twice
- Press Enter
Expected result
The second option is highlighted after step 3; after Enter the field shows it, the postcode is filled, the list closes and focus stays in City.
TC-AC-002Unchosen text is not savednegativehigh
Steps
- Type "novi" in City
- Press Tab
- Press Continue to payment
Expected result
An error "Choose a city from the list" is shown and the address is not saved. No request with cityId null is sent.
TC-AC-003Fast typing shows results for the latest queryedgemedium
Preconditions
- DevTools network throttling set to Slow 4G
Steps
- Type "novi" as fast as possible
- Wait 3 seconds
- Compare the list with the field
Expected result
Only cities matching "novi" are listed. Older responses are ignored (or never sent thanks to the debounce).
TC-AC-004Accent-insensitive search and highlightingpositivemedium
Steps
- Type "sabac"
- Clear and type "Šab"
- Clear and type "nis"
Test data
Expected matches: Šabac, Šabac, Niš
Expected result
Each query finds the city, and the matching letters (Šab, Šab, Niš) are shown in bold.
TC-AC-005Esc closes the list and keeps the textpositivemedium
Steps
- Type "subo"
- Press Esc
- Press Esc again
Expected result
After the first Esc the list closes and "subo" stays. The second Esc may clear the field, if that's the spec.
TC-AC-006Editing after choosing clears the selectionnegativehigh
Steps
- Choose "Novi Sad"
- Delete "Sad" and type "Pazar" without choosing
- Submit
Expected result
The postcode is cleared when the text changes; submitting shows an error, or "Novi Pazar" (36300) is used only if chosen or matched exactly.
TC-AC-007No results statenegativelow
Steps
- Type "xyzq"
Expected result
The list shows a helpful no-results message; screen readers hear "No results".
TC-AC-008Suggestions visible above the keyboard on a phoneedgehigh
Preconditions
- Small phone (e.g. iPhone SE) in portrait
Steps
- Scroll the form so City is near the bottom
- Tap City and type "no"
Expected result
The page scrolls or the list opens upwards / full screen so all options can be seen and tapped above the keyboard.
Tip: click a test case to expand it.
Accessibility
Autocomplete is one of the hardest components to make accessible, and custom ones often fail. Check these (the ARIAARIAHTML attributes that tell assistive technology what custom elements are and what state they're in.Open in glossary → combobox pattern):
| Key | What it should do |
|---|---|
| ↓ / ↑ | Open the list / move the active option |
| Enter | Choose the active option and close the list |
| Esc | Close the list (keep the text); a second Esc may clear |
| Tab | Leave the field (and close the list) |
- The active option is announced: focus stays in the input (so typing still works) while the screen reader reads “Novi Pazar, 2 of 4”.
Dev note: Roles and states
The input hasrole="combobox",aria-expanded,aria-controls(pointing to the list) andaria-autocomplete. The list hasrole="listbox", each optionrole="option". The active option is announced viaaria-activedescendant. - Result count: a polite live region says “4 results available” or “No results” after typing stops. Without it, screen readerScreen readerSoftware that reads the screen aloud for blind and low-vision users, like VoiceOver or TalkBack.Open in glossary → users don’t know a list appeared.
- Visible focus on the field and a clear style for the active option, different from hover. Text 4.5:1, the active-option background and field border 3:1 (WCAG 1.4.3 / 1.4.11).
- Touch targetsTouch targetThe area of the screen that responds to a tap, which should be large enough for a finger.Open in glossary →: options at least 44×44 pt on iOS and 48×48 dp on Android. On the web, WCAG 2.5.8 (AA) asks for at least 24×24 CSS px; 44×44 px (2.5.5, AAA) is the comfortable target.
- No surprise changes: suggestions must not move focus or submit the form on their own (WCAG 3.2.2 On Input, Level A).
- Zoom and small screens: at 200 % zoom and 320 px width, the list fits and scrolls (WCAG 1.4.10 Reflow, Level AA).
Read more in Accessibility basics.
Mobile vs web
- There’s no standard autocomplete control on iOS.
Dev note
Not in UIKit. Apps build one from a text field and a table, or use SwiftUI’s.searchablewith.searchSuggestions. - Test address suggestions with real addresses in different countries.
Dev note
Address suggestions often come from MapKit’sMKLocalSearchCompleteror a third-party places API. - The keyboard covers half the screen: lists usually open full screen or right below a field moved to the top. Check on the smallest iPhone you support.
- Autocorrect can change what users type (“Nis” → “Mis”). Address and city fields usually turn it off.
- Test VoiceOver (is the number of results announced?) and Dynamic Type (do long names wrap or truncate?).
Dev note
AutoCompleteTextView / MaterialAutoCompleteTextView, often inside a TextInputLayout (Material exposed dropdown menu). Compose: an editable ExposedDropdownMenuBox.- The popup can open above the field when there’s no room below. Test near the bottom of the screen with the keyboard open.
- Back should close the suggestions first, then the keyboard, then the screen.
- Test TalkBack, font scale, landscape (very little room above the keyboard) and a slow network.
Dev note
<input list="…"> with a <datalist>. It allows free text, needs no JavaScript, but looks and behaves differently in each browser and offers little control over matching.- Custom components (React, Vue, UI libraries) must follow the ARIA combobox pattern; check roles and
aria-activedescendantin DevToolsDevToolsDeveloper tools built into browsers for inspecting pages, network traffic and errors.Open in glossary → (Elements and Accessibility panes). - Check the Network tab for debouncing and the order of responses; use the “Slow 4G” and “3G” presets.
- Browser autofill can pop up on top of the app’s own suggestions; check that the two never overlap.
Dev note
Teams often setautocomplete="off"on the combobox for that reason. - Test in Chrome, Safari and Firefox, with zoom, and at narrow widths.
Related pages: matching with accents and long lists on Dropdown, the search field itself on Search bar, and debounce and race conditions in Search, filters & sorting.
Check your understanding
Quick quiz
0/5 answered · 0 correct
1.A delivery form saves the city "novi" with no postcode. What went wrong?
2.You type "novi" quickly and the list shows "Nova Varoš". What is the most likely cause?
3.The suggestion list is open. What should Esc do?
4.Which attribute lets a screen reader announce the highlighted option while focus stays in the input?
5.Search finds Šabac for "sabac", but no letters are bold. What kind of bug is this?
Key takeaways
- An autocomplete is a combobox: a text field plus a list of suggestions. Know whether it’s must-pick or free text before testing.
- The text in the field is not the value until the user chooses. Check what the form sends, especially after editing, Tab, Esc and Back.
- Debounce and ignore stale responses; test by typing fast on a slow network.
- Matching and highlighting must ignore case and accents the same way.
- Keyboard: arrows, Enter, Esc (close, keep text), Tab; the list closes on blur and outside taps; screen readers hear the result count.
- On phones, make sure the list isn’t hidden by the keyboard.
Finished this page?Nice work, this page is complete!
Mark it as done to track your progress. It's saved in this browser, no account needed.
Its review cards are now in Bites ⚡