Skip to main content
A Singapore Government Agency Website
A11Y-8L1 · mandatoryhybridAccessibility

Custom components expose name, role, and value to assistive technology

Fails when: custom control with no role or accessible name · visual state change with no ARIA state update

Requirement

Any control that isn't a native element in its default form exposes three things to assistive technology: an accessible name (what it is), a role (what kind of thing it is), and its current value/state (pressed, expanded, selected, checked). State changes update the exposed state, not just the visual.

Rationale

The accessibility checklist Essential tier ("Name, Role, Value"). The stack reduces this risk — Base UI primitives ship correct semantics — but every wrapper, every styled composition, and every hand-rolled segmented control is a chance to break the contract. A control that looks toggled but doesn't say it's toggled silently excludes AT users.

Passes when

  • A segmented status control is a group of buttons with aria-pressed (or a radiogroup), the group labelled with the thing it controls ("Attendance for Aisyah"), and the pressed state flips with the visual.
  • Disclosure/expansion uses aria-expanded on the trigger.
  • The accessible name contains the visible label text (a control labelled "Submit" is not accessibly named "send-btn-primary").

Fails when

  • A div with a click handler acting as a button (no role, no keyboard, no state).
  • Visual selection (background change) with no programmatic state change.
  • aria-label that contradicts or omits the visible text.

How to verify

Deterministic half — planned checks/nrv: scan interactive elements for role + accessible-name + state attributes; native elements pass by default. Until built: verify manually. Judgment half — the evaluator operates the component in the DOM (or reads its code) and confirms the exposed state actually tracks the visual behavior.

Also available as Markdown · catalog.yaml