Learning Track
Filter content by your role to see the most relevant sections
Selection & Actions Patterns
Design choosing well: radio vs checkbox vs switch semantics, selects sized to option counts, filter chips as reversible selection, group semantics with fieldsets and legends, and action names that say what they do.
Why This Matters
Selection is where small semantic errors compound into large user errors. A checkbox doing a radio's job allows contradictory answers. A switch doing a checkbox's job implies immediacy the system does not deliver. A select with three options makes the user open a menu to see a list that would have fit on the screen. None of these are visual problems; all of them are semantics problems—and semantics are exactly what the accessibility tree exposes, which is why the same errors that confuse users also fail audits.
The system's selection inventory—Checkbox, Select, Switch, ToggleSwitch, Chip, Shuttle—maps each control to the question it is allowed to answer, declared in the contracts and styled by the state tokens you have met throughout.
Core Concepts: Semantics First, Then Sizing
The Semantic Table
Control Question it may answer
radio exactly one of a visible small set (2–5)
checkbox any number of a visible small set, including none
switch an immediate, reversible mode toggle (state applies NOW)
select one of a set too large or too volatile to show inline
chip a reversible filter — selection that narrows content
Shuttle moving items between two named collections
The pairing rules that make it a system:
radio groups: fieldset + legend; arrows cycle; checked stays
checkbox: independent state; group label optional
switch: never inside a form's submit; it IS the submit
mixed state: a parent checkbox may show indeterminate —
never a third value the child cannot reachThe switch line carries the most misuse: a switch is an immediate action wearing a control's clothes. "Notifications" as a switch changes them now; as a checkbox in a form it changes them on submit. Users read the affordance as a promise about timing—honor it or use the other control.
Sizing the Choice
Option count is a layout decision with a semantic floor: two to five options render inline (radios or checkboxes—visible options beat hidden ones at every count a screen can hold); beyond that, a Select (the pattern page's rule of thumb from the forms family); volatile or filter-like sets become chips. The anti-pattern is the three-option select: a menu holding what a row would have shown.
Groups Are Semantics, Not Boxes
A visual cluster of choices is not a group until the tree says so: fieldset with a legend names the question the choices answer ("Delivery speed"), the arrows cycle radios within it, and the legend is the group's accessible name. Without it, a screen reader announces five orphaned radios and the user must reverse-engineer the question from the answers—the interface equivalent of Jeopardy.
Selection You Can See Coming
Chosen states draw from the state vocabulary—selected is distinct from focused is distinct from hovered (the navigation page's three-questions rule, applied to choices)—and the selection's consequence is visible: filter chips show what narrowing happened and how to undo it (the feedback family's reversibility, worn as a control). Selection without visible consequence is a trap the user sets and discovers later.
Actions Name Themselves
The actions around selection obey one rule: the button says what it does. "Delete 3 items" not "OK"; "Apply filters" not "Submit". The count in the label is the selection becoming legible in the action itself—and the destructive case pairs with the destructive ramp and the dialog pattern's confirm, as the dialogs page showed.
System Roles: Owning the Choosing
Design Impact
Designers own the question and its rendering: the option set, the count-appropriate control, the group label, and the visible consequence of choosing.
Engineering Impact
Engineers own the semantics: native controls first, groups wired (fieldset/legend or ARIA equivalents), indeterminate derived from children, switch immediacy delivered.
Accessibility Impact
The a11y function owns the announcement audit: groups named, states truthful, mixed never meaning unreachable—and the arrow-key cycling that makes radio groups fast instead of tab-heavy.
Design & Code Interplay
The design side of selection is the decision table per screen: the question, the option count, the control chosen, the group name, and the consequence visibility. Drawn once, it is the contract review's artifact; drawn never, it is re-argued per screen forever.
The semantics, as the tree needs them:
// Radio group: the question names the group
<fieldset>
<legend>Delivery speed</legend>
<label><input type="radio" name="speed" value="std" /> Standard</label>
<label><input type="radio" name="speed" value="exp" /> Express</label>
</fieldset>
// Indeterminate is derived, never a value
checkbox.indeterminate = selected.length > 0
&& selected.length < options.length;
// Switch: immediate — this IS the action
<Switch checked={muted} onChange={setMuted}>Mute notifications</Switch>
// Actions count the selection
<Button variant="destructive" onClick={confirmDelete}>
Delete {selected.length} {selected.length === 1 ? 'item' : 'items'}
</Button>Applied Example: A Table With Bulk Selection
The stress test—a data table with bulk actions:
- Per-row: a checkbox, independent, labeled by the row's name (not "select row" noise—the label is the content).
- Header: the select-all checkbox, indeterminate when partial, its state derived from children—never lying about what it will do.
- Actions: appear when selection exists, named with counts ("Export 12"), destructive ones confirmed via the dialog pattern with safe-default focus.
- Keyboard: the whole flow operable— space toggles, shift-space ranges (declared behavior, tested in the e2e walk), Escape clears.
- Announcement: selection changes reach the tree (the action bar's count as a polite status)—sighted users see the count; everyone hears it.
Constraints & Trade-offs
- Inline visibility vs space: showing options beats hiding them until it costs the layout; the crossover is honest (a screen cannot hold twenty radios) and the select is the concession, not the default.
- Switch immediacy vs form semantics: immediate application feels fast and fragments submission models; deferred forms batch cleanly and hide pending state. One model per screen.
- Chips vs a filter dialog: chips keep filters visible and reversible; dialogs scale to complex filters and hide state. Visible-until-complex is the default ordering.
Common Pitfalls & Failure Modes
1. Checkbox doing radio work
Checkboxes for a one-of set allow contradictory selections; radios for any-of sets strand single answers. The semantic table is not a suggestion.
2. The ungrouped group
<!-- Bad: Five radios, no question -->
<input type="radio"> A <input type="radio"> B …
<!-- Good -->
<fieldset><legend>Plan</legend> …radios… </fieldset>3. Indeterminate as a choice
The mixed state describes children; a user who can click into it has been offered a state that means nothing.
4. Selects holding three options
A menu hiding a list the screen could show. Radios or checkboxes at every small count.
5. Actions named OK
"OK" names nothing. Buttons say what they do; with selection, they say it with counts.
Verification Checklist
Additional Resources
- Forms — the fields selections live inside (
/blueprints/ux-patterns/forms) - Dialogs — destructive selection confirms (
/blueprints/ux-patterns/dialogs) - ARIA APG patterns — checkbox/radio reference behaviors (
https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/)
Related Concepts
Reflection Questions
Apply This Concept
Take a settings screen you know and audit it against the semantic table. Which control answers a question it is not licensed to, and what contradictory state can a user reach because of it?
Reflect
A team wants filter chips that apply only on a Save button, citing consistency with the form. What promise do chips make that this breaks, and what is the honest alternative?
