Skip to content
Bugwise
Menu
UI Components

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.

35 min Inputs & selection iOS · Android · Web Also called: Typeahead, Combo box, Suggestions, Autosuggest

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

novi23
Novi Sad21000
Novi Pazar36300
Novi Bečej21220
Novi Kneževac23330
456

🔊 “4 results available”7

  1. 1

    Label

    Says what to type ("City"). Visible and connected to the input, like any text field.

  2. 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. 3

    Clear button

    Empties the field and the selection. Needs a name ("Clear city") and a 44 pt / 48 dp touch area.

  4. 4

    Suggestion list (listbox)

    Opens below the field after enough characters. Must close on Esc, on selection and when focus leaves.

  5. 5

    Active option

    Moved with the arrow keys, chosen with Enter. Clearly visible, and different from "selected".

  6. 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. 7

    Result count (status)

    Invisible on screen but announced: "4 results available". Also says "No results".

List, inline, or both

StyleWhat happensTypical use
ListA list of matching options opens under the fieldCities, addresses, products, people
InlineThe rest of the word is filled in and selected; typing on replaces itBrowser address bar, email domains
List + inlineThe list opens and the first match is also completed in the fieldSome address bars and code editors
Dev note
In ARIA terms these are 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

ComponentYou type…You get…
Autocomplete / combo boxPart of a nameSuggestions; one becomes the value (or free text)
Dropdown / selectNothing (or one letter to jump)One option from a fixed list
Search barA queryA results page; suggestions are only shortcuts
Chips / token fieldPart of a name, many timesSeveral selected values shown as chips
Browser autofillNothingSaved 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

Web

A 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.

Type 2 letters to see suggestions

Form value: null

Exposed dropdown menu

Android · Material 3

Material'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

iOS

On 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

Web

The 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

Web

When 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

8–10 am12–2 pm6–8 pm

Three options, all visible, one tap.

Typing to find one of three

Delivery time

Start typing…

Type what? Users have to guess the options before they can see them.

Must pick: show what was chosen

City

Novi Sad 21000

✓ 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

novi

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

#BugWhat you seeTypical severity
1Typed text saved, nothing chosen“novi” is saved as the city; no postcode, no idHigh
2Stale resultsThe list shows results for an older queryMedium–High
3No keyboard supportArrows do nothing; Enter submits the formHigh (for affected users)
4Esc clears the fieldInstead of closing the list, Esc wipes what you typedMedium
5List won’t closeIt stays open after Tab or a tap outside and covers the formMedium
6Edited after choosingChange “Novi Sad” to “Novi Pazar” by typing: the old id is still sentHigh
7Accents and case“sabac” finds nothing, or finds Šabac but highlights nothingMedium
8No empty or loading stateNothing appears, so users think the field is brokenMedium
9Request on every keystrokeTen requests for ten letters; flicker and rate limitsMedium
10Hidden by the keyboardOn a phone, the list opens behind the on-screen keyboardHigh
11Silent for screen readersNo result count, options not announcedHigh (for affected users)
12Special 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.

Minimum characters
Matching
Highlighting
Debounce
Late responses

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.

Found0/6
shop.example.com

FreshBasketCheckout · 1 of 3

Where should we deliver?

Network log
  • Type a city to see requests…
  1. 1

    Hint: Type "novi", don't pick anything, and press Continue to payment. Read the network log.

  2. 2

    Hint: Type "kra" and press the Down arrow, then Enter.

  3. 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. 4

    Hint: Type "subo" so the list opens, then press Esc.

  5. 5

    Hint: Type "kr", then click the Full name field or press Tab.

  6. 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 keyboard

Steps

  1. Tab to City
  2. Type "kra"
  3. Press Down twice
  4. 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 saved

Steps

  1. Type "novi" in City
  2. Press Tab
  3. 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 query

Preconditions

  • DevTools network throttling set to Slow 4G

Steps

  1. Type "novi" as fast as possible
  2. Wait 3 seconds
  3. 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 highlighting

Steps

  1. Type "sabac"
  2. Clear and type "Šab"
  3. 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 text

Steps

  1. Type "subo"
  2. Press Esc
  3. 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 selection

Steps

  1. Choose "Novi Sad"
  2. Delete "Sad" and type "Pazar" without choosing
  3. 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 state

Steps

  1. 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 phone

Preconditions

  • Small phone (e.g. iPhone SE) in portrait

Steps

  1. Scroll the form so City is near the bottom
  2. 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):

KeyWhat it should do
↓ / ↑Open the list / move the active option
EnterChoose the active option and close the list
EscClose the list (keep the text); a second Esc may clear
TabLeave 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 has role="combobox", aria-expanded, aria-controls (pointing to the list) and aria-autocomplete. The list has role="listbox", each option role="option". The active option is announced via aria-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 .searchable with .searchSuggestions.
  • Test address suggestions with real addresses in different countries.
    Dev note
    Address suggestions often come from MapKit’s MKLocalSearchCompleter or 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
Views: 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
Native: <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-activedescendant in 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 set autocomplete="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. 1.A delivery form saves the city "novi" with no postcode. What went wrong?

  2. 2.You type "novi" quickly and the list shows "Nova Varoš". What is the most likely cause?

  3. 3.The suggestion list is open. What should Esc do?

  4. 4.Which attribute lets a screen reader announce the highlighted option while focus stays in the input?

  5. 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 ⚡
Esc

Type to search the whole site.