FORMS · FORM ELEMENTS

Selects

Native, custom, multi and combobox. Every list opens, filters, groups and speaks to a screen reader.
THEME
DENSITY
01

Playground

Kind, size, state, label — the select and its a11y tree update live
PREVIEWLive · pick, then close
Project owner
The owner approves the budget
ACCESSIBILITY TREE
rolecombobox · select-only
name"Project owner"
expandedfalse
valuenone
active option—
statesrequired
Settings
KIND
SIZE
LABEL
STATE
CODE
<Select label="Project owner" options={people} groupBy="team" renderIcon={Avatar} description={p => p.role} clearable hint="The owner approves the budget" required/>
02

Variants

10 patterns, all working
Native vs custom<select> · role="combobox"
Phones show the OS wheel or sheet
Custom select
Type a letter to jump — try “s”
Native gets the OS picker on phones for free. Custom adds badges, search and rich rows — and has to rebuild the keyboard support itself.
Rich optionsavatar · name · role
Project owner
Tom is on leave — listed, but can’t be picked
Grouped + search10 timezones · 4 regions
Timezone
Search matches city, offset and region
Multi · chipsSelect all · Clear in the footer
Publish to
Multi · counttrigger shows “4 of 9”
Visible columns
ProjectClientOwnerStatusBudgetSpentStartDueTags
Creatable comboboxtype · Enter · create
Labels
BrandingUrgent
Type a new name and press Enter to create it. Backspace removes the last chip.
Async optionsdebounce 350 ms · loading · empty
Client
Results load after you stop typing
DependentCountry → City
Country
City
Unlocks after you choose a country
Status with colourdot + text, never colour alone
Status
Short lists2–5 options: show them all
Priority
Billing cycle
03

States

8 trigger states × 3 sizes, plus option states
DEFAULTFOCUSOPENFILLEDERRORSUCCESSDISABLEDREAD-ONLYS · 36M · 44L · 52
Option statesinside the panel
Alex ReyesArt director
DEFAULT
Jon ReyesHover or keyboard
ACTIVE
Olivia Lanearia-selected="true"
SELECTED
Olivia LaneEnter keeps it
SELECTED + ACTIVE
Liam Novakaria-disabled · on leave
DISABLED
Spectrigger · panel · option
TriggerSame box as inputs: 36 / 44 / 52 px, 1.5 px border, 16 px chevron
OpenRing stays on, chevron rotates 180°
Panel6 px from the trigger, 16 px radius, max 280 px, scrolls inside, flips up when needed
Option32 / 36 / 42 px, 10 px radius, check on the right
Group10 px caps label, role="presentation", never focusable
Multi18 px checkbox on the left, panel stays open
Empty / loadingSays what happened: “No matches for …”, “Searching clients…”
04

Behavior

Keyboard, collision, virtualised list, mobile sheet
Keyboardarrows · Home/End · type-ahead
Typeface
Closed + a letter selects directly, like a native select
↓ ↑Open, then move through optionsEnter · SpaceOpen, or pick the active optionHome · EndFirst / last optionA–ZType-ahead — jumps to the next matchEscClose, focus stays on the triggerTabClose and move to the next field
KEY LOGbuffer empty
Focus the select and use the keyboard.
Collisionflips up when there’s no room below
POSITION IN VIEWPORT
VIEWPORT
Open the select — the measurement shows here
Long list288 options · virtualised · sticky group
Start time
PageUp / PageDown jump 8 rows. Only the visible rows are in the DOM.
Mobile sheetbelow 480 px the list becomes a bottom sheet
New event
Title
Moodboard review
Reminder
Rows are 50 px tall. Tap the backdrop or Done to close.
05

In Avava

Project filters and an Assign task form
Projects · filtersmulti · single · chips · live table
Client
Status
Owner
Due
10 of 10 projects
PROJECTCLIENTSTATUSOWNERDUE
Spring campaignNova AthleticsActiveOlivia LaneSat, Oct 24
Packaging refreshLume GoodsActiveJon ReyesOct 31
Brand bookAtelier NoirPausedAlex ReyesDec 13
Product shootKiln & CoActiveJakob MoreauOct 13
App onboardingOrbit LabsLeadIda SvenssonOct 31
Lookbook SS27Sable StudioActiveAlex ReyesSat, Oct 24
Type specimenForma TypeLeadZoe DahlDec 13
Clinic signageHalo HealthArchivedLiam NovakOct 13
Annual reportMosaic PressActiveAna PetitOct 31
Sonic logoDrift AudioPausedIda SvenssonSat, Oct 24
Assign tasksearch · segmented · creatable · validation
Assignee
Due
Priority
Labels
Optional · Enter creates a new label
Task and Assignee are required
Assignedwhat the form produced
Nothing assigned yetFill the form and press Assign task.
06

Rules & a11y

When to use what, anatomy, ARIA
Which control?count the options first
2–5, all fit
Segmented or radio cardsPriority, billing cycle
5–15 options
SelectStatus, owner, due date
15+ or unknown
Select with searchTimezone, client
Pick several
Multi-select with chipsChannels, reviewers, filters
Free text + suggestions
Creatable comboboxLabels, tags
Plain text, mobile-first
Native <select>Country at checkout
Anatomylabel · trigger · panel · option
Project owner1
Olivia Lane
2
DESIGN
Olivia Lane
Alex Reyes4
3
1Label — visible, linked with aria-labelledby
2Trigger — shows the chosen value, never a generic “Selected”
3Panel — listbox, opens under the trigger or flips up
4Active option — aria-activedescendant — focus stays on the trigger
Screen readersARIA 1.2 select-only combobox
✓role="combobox" aria-haspopup="listbox"On the trigger, with aria-expanded and aria-controls
✓role="listbox" · role="option"Panel and rows; group labels are role="presentation"
✓aria-activedescendant="owner-o-3"Moves with the arrows — DOM focus never leaves the trigger
✓aria-selected · aria-disabledOn every option, not only the chosen one
✓aria-multiselectable="true"On multi-selects; the panel stays open after each pick
✓Esc returns focus to the triggerTab closes without picking, like a native select
DO✓Use a native select for plain text on mobile-first forms✓Show the chosen value in the trigger, with its avatar or dot✓Scroll the selected option into view when the list opens✓Add search once the list passes about 15 options✓Return focus to the trigger after closing
DON’T✕Use a select for 2–3 options — show them as radios✕Open on hover or close the list on scroll✕Hide the chevron — it’s the affordance✕Reset a dependent field silently — say why it cleared✕Put actions like “Delete” inside an option list