ARIA has several states that all seem to mean "this one is on" — aria-checked, aria-selected, aria-pressed and aria-current. Which widget does each belong to?
answer
- four words for "on", four different roles
- selection needs a container to be selected in
- toggle button versus switch
- "you are here" is not selection
- tokens, not booleans, for one of them
basics
~20 saria-checked belongs to checkboxes, radios and switches; aria-selected to items chosen inside a composite such as a listbox option, tab or grid row; aria-pressed to toggle buttons; and aria-current marks the current item in a set, like the active nav link.
solid answer
~40 sThey look interchangeable and are not — each is tied to particular roles. `aria-checked` is for controls whose whole purpose is a checked value: `checkbox`, `radio`, `switch`, `menuitemcheckbox`, `menuitemradio`; it takes `"true"`, `"false"` or `"mixed"` for a tri-state checkbox. `aria-selected` marks the chosen item **within a composite** — an `option` in a `listbox`, a `tab` in a `tablist`, a `row` or `gridcell` in a grid. `aria-pressed` is only for a toggle button, `role="button"`, and also supports `"mixed"`. `aria-current` is different in kind: it does not express selection at all, it says "you are here" within a set of related items, taking token values `page`, `step`, `location`, `date`, `time` or `true` — the standard way to mark the current page's link in navigation. Picking the wrong one announces the wrong widget.
go deeper
Learn the four pairings by heart: checked goes with checkbox, radio and switch; selected with options and tabs; pressed with toggle buttons; current with the active nav link.
Explain that each state is bound to specific roles and say why selection needs a containing composite while checkedness does not, including where the "mixed" value is valid.
Show you choose from the widget's role rather than its visual highlight, and describe how you keep these volatile states from drifting out of sync with the rendered UI in a shared component set.
Be ready to standardise the mapping across a design system — which of pressed versus switch a product uses for the same visual affordance, and why a single documented answer beats each team improvising.
## Why four states for one idea English collapses "ticked", "chosen", "toggled on" and "you are here" into the same vague notion of *on*. Assistive technology does not: the state a screen reader announces is bound to the role of the element carrying it, and each of these four states implies a different kind of control with different user expectations. Getting them wrong does not merely lose nuance — it announces a widget the user does not have. ## aria-checked — the value of a checkable control Used with `role="checkbox"`, `role="radio"`, `role="switch"`, `role="menuitemcheckbox"` and `role="menuitemradio"`. Values are `"true"`, `"false"` and `"mixed"`, the last representing a partially-checked parent in a tree of checkboxes (a "select all" box where some children are ticked). `mixed` is valid for checkbox-style roles but not for `radio` or `switch`, both of which are strictly binary. For all these roles `aria-checked` is a **required** state — the role's contract is unmet without it. The important context is that native `<input type="checkbox">` and `<input type="radio">` expose their checked state through the DOM property, not through an ARIA attribute. You do not add `aria-checked` to a native checkbox; the state you would be duplicating is already there, and a hand-written value can drift out of sync with the real one. ## aria-selected — chosen inside a container Selection is a relationship between an item and the composite that owns it. `aria-selected` is supported on `option`, `tab`, `row`, `gridcell`, `columnheader` and `rowheader` — always something living inside a `listbox`, `tablist` or `grid`. It is required on `option` and on `tab`. ```html <div role="tablist"> <button role="tab" aria-selected="true" id="t1">Overview</button> <button role="tab" aria-selected="false" id="t2">Pricing</button> </div> ``` The container's `aria-multiselectable` property says whether more than one item may carry `aria-selected="true"` at a time. The distinguishing feature versus `aria-checked` is context: selection only means something relative to a set of siblings, whereas checkedness is a property of one control standing alone. ## aria-pressed — the toggle button Only for `role="button"`, meaning a `<button>` whose activation flips a mode rather than performing a one-shot action: bold in a text editor, mute on a player, a filter chip that stays on. Values are `"true"`, `"false"` and `"mixed"`. Screen readers announce it as "pressed" or "not pressed". The frequent confusion is with `role="switch"`, which is a distinct role using `aria-checked` and reads as "on"/"off". Both model a two-state control; choose by the mental model you want, then use the state that role requires. Never put `aria-pressed` and `aria-checked` on the same element — the two contradict each other about what kind of widget this is. ## aria-current — location, not selection `aria-current` is the odd one out because it does not describe a control at all. It marks which item in a set of related items is the current one, and it takes token values rather than booleans: `page`, `step`, `location`, `date`, `time`, plus the generic `true` (and `false`, the default). Its canonical use is the navigation link pointing at the page you are already on: ```html <nav> <a href="/pricing" aria-current="page">Pricing</a> <a href="/docs">Docs</a> </nav> ``` Use `step` for the active step of a wizard, `date` for today in a calendar grid, `location` for the current position in a flow or breadcrumb trail. The tokens are not free-form: an unrecognised value is treated as `true`. ## Choosing correctly Work from the role outward, never from the visual design inward. Ask what kind of control this is — a checkable value, an item chosen from a set, a mode toggle, or a marker of where the user is — pick the role that matches, then use the state that role actually supports. A styled-blue "selected" nav link is not selected in the ARIA sense; it is `aria-current="page"`. A filter chip that stays highlighted is a toggle button with `aria-pressed`, not an option with `aria-selected`, unless it genuinely lives inside a listbox. And remember these states are volatile by definition: whatever flips the visual treatment must flip the attribute in the same operation, or the accessibility tree ends up describing the previous state of the interface.
- When would you use role="switch" instead of a toggle button with aria-pressed?Use `role="switch"` when the control reads as an on/off setting that takes effect immediately — notifications on, dark mode on. Use a toggle button with `aria-pressed` when it reads as a pressed-in tool or mode, like bold in an editor toolbar. A switch carries `aria-checked` and is announced "on"/"off"; a toggle button is announced "pressed"/"not pressed". Never combine the two states.
- What does aria-checked="mixed" represent, and where is it invalid?`mixed` represents a tri-state checkbox — typically a parent "select all" whose children are partly ticked. It is valid for `checkbox` and `menuitemcheckbox`. It is not valid for `radio` or `switch`, which are strictly binary; a `mixed` value there is meaningless and assistive technology will not report a coherent state.
- Should you add aria-checked to a native <input type="checkbox">?No. The native control already exposes its checked state to the accessibility tree from the DOM property, so an ARIA attribute duplicates it and can contradict it. If script toggles the real checkbox but forgets the attribute, the tree reports the stale hand-written value. `aria-checked` is for elements given a checkbox role that have no native state to expose.
- How would you mark the active link in a breadcrumb trail?With `aria-current`, choosing the token that fits: `page` for the link to the current page, or `location` for the current position within a flow when it is not literally the current URL. Selection states like `aria-selected` are wrong here because a breadcrumb is not a composite widget with selectable items — the user is not choosing anything.
saying these in an interview costs you the question
- Using aria-selected on a navigation link for the current page
- Adding aria-checked to a native checkbox input
- Putting aria-pressed and aria-checked on the same control
- Treating aria-current as a boolean with no token values
- Assuming aria-selected works on any element you highlight