Dropdown / Select
A compact control that hides a list of options until you open it. Learn the native and custom variants, when a dropdown is the wrong choice, and the bugs testers find in long lists and dependent fields.
Choosing your country at checkout, a T-shirt size in a fashion app, a sort order in a hotel search: whenever an app needs one answer from a known list, there’s a good chance it uses a dropdownDropdownA control that shows the selected option and opens a list of options when tapped.Open in glossary →. It saves space by hiding the options until you need them.
That hiding is also its weakness. Testers have to open it, scroll it, search it, use it with a keyboard, and check what happens when another field changes. Let’s see how.
What is a dropdown?
A dropdown (also called a select or picker) is a closed field that shows the current value and opens a list of options when you tap it. You pick one option (or several, in a multi-select), and the list closes again.
You’ll usually see dropdowns used for:
- Long, known lists: country, state, language, currency.
- Settings with many values: sort order, items per page, time zone.
- Product choices: size, color, quantity.
- Dependent choices: car make → model, country → city.
Anatomy
Delivery country
We currently ship to the EU only.
- 1
Label
Says what you are choosing. Stays visible after a value is picked.
- 2
Trigger (field)
Shows the current value, or a placeholder like "Select…" when nothing is chosen.
- 3
Indicator (chevron)
Signals that a list opens. Often flips when the menu is open.
- 4
Menu (listbox)
The floating list of options. Scrolls when there are many.
- 5
Option
One choice. Can be disabled (dimmed, not selectable).
- 6
Selected option
The current value, marked with a checkmark or a tint.
- 7
Highlighted option
Where the mouse or keyboard focus is right now. Not the same as selected!
- 8
Helper text
Extra guidance, replaced by an error message when needed.
How it differs from similar components
| Component | Options visible | Selection | Best for |
|---|---|---|---|
| Dropdown / select | Hidden until opened | One (or many, in a multi-select) | 5–15 options when space is tight |
| Combo box (searchable dropdown) | Hidden; filtered as you type | One | Long lists: countries, cities, airports |
| Segmented control | All, in one row | Exactly one | 2–5 short options that switch a view |
| Radio buttons | All, stacked | Exactly one | 2–6 options, especially with longer labels |
| Bottom sheet / picker | Slides up from the bottom (mobile) | One or many | Long or rich lists on phones, with search or descriptions |
| Menu | Hidden until opened | None: you trigger an action | Commands like Edit, Share, Delete, not values |
Dev note
On the web it’s a <select> element or a custom listbox/combobox. iOS uses a pop-up button (a menu with a checkmark) or a picker (the scrolling wheel). Material Design on Android calls it an exposed dropdown menu, and Android developers often say Spinner. A menu that runs actions is not a dropdown, even if it looks like one.
Designs & variants
Native dropdowns are drawn by the browser or the operating system, so they’re usually robust. Custom ones look nicer, but every behavior (keyboard, positioning, screen readers) has to be rebuilt by the team, and that’s where bugs hide.
All of these work: open them with the mouse, then try the keyboard (Tab, arrows, Enter, Esc, or type a letter).
Native select
WebA real <select>. The browser draws the list, so on phones you get the system picker for free. Hard to style, easy to trust.
Custom dropdown
WebBuilt from scratch to match the brand. Looks nicer, but keyboard support, screen readers and positioning are now the team's job.
Pop-up button menu
iOSTap the blue value and a menu appears right there, with a checkmark on the current choice. Good for 3–7 options.
Shoe size (EU): 40
Wheel picker
iOSScroll the wheel until your value sits in the band. Classic for dates, times and sizes. Test that the value actually saves when you stop.
Exposed dropdown menu
Android · Material 3An outlined field with a floating label and a menu that opens underneath. The selected item gets a tinted background.
Searchable combo box
AllType to filter long lists. A good one ignores case and accents: try 'cote', 'sao tome' or 'turkiye'.
Multi-select
Web · AndroidCheckboxes inside a dropdown. The menu stays open while you pick. Test 0, 1, all, and how the field shows many choices.
Dependent dropdowns
AllThe city list depends on the country. City stays disabled until a country is chosen, and resets when the country changes.
When to use it
A dropdown is a good choice when:
- There are more than about 5 options and showing them all would take too much space.
- The options are familiar to users (they know their country, they don’t need to compare).
- There’s a sensible default, or the user picks once and rarely changes it.
- For long lists (15+), add search. Then it becomes a combo box.
Good and bad uses
Few options: show them all
Both options are visible and one tap away.
Hiding two options in a dropdown
Two taps to see two options, and nothing tells the user there’s a price difference. Use radio buttons or a segmented control.
A clear placeholder
Required for shipping
The user has to make a real choice. Submitting without one shows an error.
First option pre-selected
Users skip the field without noticing, and the shop receives hundreds of orders “from Afghanistan”. A wrong default is worse than none.
Long list: let users search
Countries, cities, airports and banks belong in a combo box: type “cro” and Croatia appears. On phones, a full-screen list or bottom sheet with a search field works well too. Try the searchable combo box in the gallery above.
Long list: endless scrolling
- Afghanistan
- Åland Islands
- Albania
- Algeria
- American Samoa
- Andorra
- Angola
- Anguilla
Around 200 countries and territories, 5 visible at a time. Scrolling to “Croatia” is slow, and finding “United Kingdom” is painful.
Common bugs
These are the dropdown bugs testers report most often.
| # | Bug | What you see | Typical severity |
|---|---|---|---|
| 1 | Dependent field not reset | You change the country, but the old city stays selected, so the order ships to “Zagreb, Serbia” | High |
| 2 | Menu clipped or off-screen | Near the bottom of the screen (or inside a card) the list is cut off and the last options can’t be reached | High |
| 3 | No keyboard support | Tab skips the dropdown, or arrows, Enter and Esc do nothing | High (for affected users) |
| 4 | Strict search | “ceske” doesn’t find “České Budějovice”; “zagreb” doesn’t find “Zagreb” | Medium |
| 5 | Unsorted list or duplicates | Cities appear in random order, “Split” is listed twice | Low–Medium |
| 6 | Doesn’t close | Clicking outside or scrolling the page leaves the menu floating on top of the form | Medium |
| 7 | Selected value not shown | After choosing, the field still says “Select…” (but the value was saved) | Medium |
| 8 | Wrong default | The first option is pre-selected, or the saved value isn’t shown when you come back to edit | High |
| 9 | Placeholder can be submitted | “Select a country” is accepted as if it were a real value | Medium |
| 10 | Long labels truncated | “Tomorrow, 16:00–2…” or long translations are cut off in the field or menu | Medium |
| 11 | Highlighted ≠ selected | Moving the mouse over an option changes the value without clicking | Medium |
| 12 | Screen reader silence | VoiceOver or TalkBack says “button” or “clickable” with no label and no value | High (for affected users) |
Stress-test it
A long list is only usable if search and sorting respect real names with real letters. Compare a naive implementation with a robust one:
🧪 Search & sort lab
A long list needs search, and search is where dropdowns break. Type a query (or pick one) and compare a naive search with a robust one.
Sort order
The order the data came from the database. Users can't predict where anything is.
Naive search
label.includes(query)
- Zagreb
- Šibenik
- Split
- Čakovec
- Đakovo
- Osijek
- Beograd
- Niš
- Novi Sad
- Ljubljana
- Kraków
- Łódź
- Gdańsk
- Zürich
- München
- Köln
- Malmö
- Wien
- Brno
- Plzeň
- České Budějovice
- São Paulo
- Ćuprija
- Antwerpen
24 of 24 cities
Robust search
ignore case + accents + extra spaces
- Zagreb
- Šibenik
- Split
- Čakovec
- Đakovo
- Osijek
- Beograd
- Niš
- Novi Sad
- Ljubljana
- Kraków
- Łódź
- Gdańsk
- Zürich
- München
- Köln
- Malmö
- Wien
- Brno
- Plzeň
- České Budějovice
- São Paulo
- Ćuprija
- Antwerpen
24 of 24 cities
Empty query: both show the whole list. Now try "ceske" or "lodz".
Find the bug
The checkout form below has six bugs in its dropdowns. Test it like a real customer, then like a tester:
- Choose a country and city, then change the country.
- Search for countries in lowercase and without accents.
- Try every option in every list, including the last ones.
- Put the mouse away and use only the keyboard.
- Open a list and click somewhere else.
🐞 Bug hunt: Checkout
This demo has 6 hidden bugs. Explore it like a tester, then check your findings.
Checkout
Shipping address
City
Try the mouse and the keyboard (Tab, arrows, Enter, Esc).
Network log
Place the order to see the request body…
- 1
Hint: Choose a country and a city, then change the country.
- 2
Hint: Search for a country in lowercase, or without accents.
- 3
Hint: Open Delivery slot and try to pick a Saturday slot with the mouse.
- 4
Hint: Press Tab from the Country field.
- 5
Hint: Open the City list, then click somewhere else on the page.
- 6
Hint: Read the city list for Hrvatska or Srbija carefully.
How to test it
Checklist
Dropdown test checklist
0 of 14 checked
Example test cases
TC-DD-001Selected value is displayed after choosingpositivehigh
Steps
- Open Checkout
- Open the Delivery slot dropdown
- Choose "Tomorrow, 12:00–16:00"
Expected result
The menu closes and the field shows "Tomorrow, 12:00–16:00".
TC-DD-002City resets when the country changesnegativehigh
Steps
- Choose Country "Hrvatska"
- Choose City "Zagreb"
- Change Country to "Srbija"
- Open the City dropdown
Expected result
City is cleared and shows the placeholder. The list contains only Serbian cities.
TC-DD-003Search ignores case and accentspositivemedium
Steps
- Click the Country field
- Type "ceska"
- Clear and type "HRVATSKA"
- Clear and type "osterreich"
Expected result
Each query shows the matching country: Česká republika, Hrvatska, Österreich.
TC-DD-004Search with no resultsnegativelow
Steps
- Click the Country field
- Type "xyz"
Expected result
A "No matches" message is shown. Pressing Enter does not select anything.
TC-DD-005Last option can be selected near the bottom of the screenedgehigh
Preconditions
- Phone in landscape, or browser window 600 px high
Steps
- Scroll so the Delivery slot field is near the bottom edge
- Open the dropdown
- Tap the last option
Expected result
All options are visible (the menu opens upwards or scrolls), and the last option can be selected.
TC-DD-006Keyboard-only selectionpositivehigh
Steps
- Press Tab until the City dropdown is focused
- Press Arrow Down
- Press Arrow Down twice
- Press Enter
- Press Arrow Down, then Esc
Expected result
Focus is visible on the field; the list opens; the highlight moves; Enter selects the 3rd city and closes the list; Esc closes the list without changing the value.
TC-DD-007Clicking outside closes the menupositivemedium
Steps
- Open the City dropdown
- Click on an empty area of the page
Expected result
The menu closes and the previously selected value is unchanged.
TC-DD-008Required dropdown blocks submitnegativehigh
Steps
- Leave Delivery slot on "Choose a slot"
- Fill in all other fields
- Tap "Place order"
Expected result
The order is not placed. The Delivery slot field shows "Choose a delivery slot".
TC-DD-009Saved value is shown when editingpositivemedium
Preconditions
- An address with Country "Slovenija" and City "Maribor" is saved
Steps
- Open Account › Addresses
- Tap Edit on the saved address
Expected result
Country shows "Slovenija" and City shows "Maribor" (not the placeholder or the first option).
Tip: click a test case to expand it.
Accessibility
Custom dropdowns are one of the most common accessibility failures on the web. Check these:
- Keyboard (web): the dropdown is reachable with Tab; Enter, Space or ↓ open it; arrows move the highlight; Enter selects; Esc closes and returns focus to the field. Typing a letter jumps to matching options.
- Screen readers (VoiceOver / TalkBackScreen readerSoftware that reads the screen aloud for blind and low-vision users, like VoiceOver or TalkBack.Open in glossary →) should announce the label, the current value, that it’s a pop-up / combo box, and whether it’s expanded. Inside the list, each option should be announced with its position (“Zagreb, 3 of 6”) and selected state.
Dev note
In code:role="combobox"+aria-expandedon the field,role="listbox"androle="option"+aria-selectedin the menu. - Visible focus: both the field and the highlighted option need a clear focus indicator, not only a subtle color.
- Highlighted vs selected must look different, so keyboard users know what Enter will choose.
- Contrast (WCAGWCAGThe Web Content Accessibility Guidelines, the main international standard for accessibility.Open in glossary →): option text at least 4.5:1; the field border and chevron at least 3:1.
- 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 pt tall on iOS and 48 dp on Android.
- Combo boxes should announce the number of results as you type (“5 results”).
Mobile vs web
- Pop-up buttons show a menu with a checkmark. Good for short lists.
Dev note
UIButtonwith a menu, orPickerwith the.menustyle in SwiftUI. - Wheel pickers are used for dates, times and sizes. Test that the value saves when you stop scrolling, not only when you tap Done.
Dev note
UIPickerView,UIDatePicker,.wheelstyle. - A web
<select>in Safari opens the native iOS picker. Check long option labels there, because they get truncated. - Long lists usually open a new screen with a search field instead of a menu.
- Test with VoiceOver (the rotor and swipe up/down adjust picker values) and the largest Dynamic Type size.
- Material 3 exposed dropdown menu; older apps use a spinner.
Dev note
ExposedDropdownMenuBoxin Compose,TextInputLayout+AutoCompleteTextViewin Views; the older one is aSpinner. - The menu can open above the field when there’s no room below. Test near the bottom of the screen and with the keyboard open.
- The system Back button should close an open menu without leaving the screen.
- Long lists often use a bottom sheet or a full-screen search instead.
- Test with TalkBack, font scale and display size settings.
- A native
<select>is the safest choice: keyboard, screen reader and mobile pickers work out of the box. - Custom dropdowns (React, Vue, UI libraries) must follow the ARIA combobox / listbox pattern. Check the roles in DevToolsDevToolsDeveloper tools built into browsers for inspecting pages, network traffic and errors.Open in glossary →.
- Test positioning: near the bottom of the window, inside scrolling containers, inside modals and cards with hidden overflow.
- Test zoom at 200% and small viewports: does the menu still fit?
- Cross-browserCross-browser testingChecking a website works and looks right in different browsers and browser versions.Open in glossary →: native selects look very different in Chrome, Safari and Firefox; check each one.
Check your understanding
Quick quiz
0/5 answered · 0 correct
1.A form asks "Gift wrap?" with only "Yes" and "No". Which component fits best?
2.You choose Hrvatska and Zagreb, then change the country to Srbija. The city still shows Zagreb. What kind of bug is this?
3.Which search query is MOST likely to reveal a search bug in a city combo box?
4.The last two options of a dropdown are cut off at the bottom of a card. What should the dropdown do?
5.What is the difference between a highlighted and a selected option?
Key takeaways
- A dropdown hides a known list of options behind a compact field. Use it for 5+ familiar options; add search for long lists.
- For 2–5 options, radio buttons or a segmented control are usually better. A menu runs actions and is a different component.
- Prefer a clear placeholder over a random pre-selected first option, and make required dropdowns block submit.
- The classic bugs: dependent fields not reset, clipped menus, no keyboard support, strict search, unsorted or duplicate options, and menus that won’t close.
- Always test the first and last option, changing the parent field, lowercase and accent-free search, and keyboard-only use.
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 ⚡