Skip to content

Validation

C-53 · Components · Inputs

All elements · Validation on the Components page

Last checked 2026-10-22 · Awaiting approval · Accessibility tests

Copies the bun run a11y:approve command for Validation.

Validation

C-53WCAG 2.2 AA · Passed

A live checklist of what a Field's value must meet, such as a new password's rules, ticked off as the user types (USWDS Validation). Each requirement says in text whether it is met; one polite live region reports the count after the user pauses, never per keystroke. The input names the checklist in aria-describedby.

Axis Values
__item[data-state] unmet · met; the matching __unmet (circle) or __met (filled check) icon shows, and the visually hidden __state says "not met" or "met"
data-invalid after a failed submit: unmet items take the error ink; pair it with the Field's data-invalid, aria-invalid and an error message
__title · ul.__list[aria-labelledby] · __text "Your password must have", and one item per requirement
__summary[role="status"] the one polite live region: "2 of 4 requirements met", written after a pause and only when the count changes
input aria-describedby the checklist's id (after the error message's when invalid)
Live: type a password (the count is announced after you pause)

Your password must have

  • At least 12 characters, not met
  • An uppercase letter (A–Z), not met
  • A number (0–9), not met
  • A symbol, such as ! or #, not met

States: empty · partly met · all met · after a failed submit

Your password must have

  • At least 12 characters, not met
  • An uppercase letter (A–Z), not met
  • A number (0–9), not met
  • A symbol, such as ! or #, not met

Your password must have

  • At least 12 characters, not met
  • An uppercase letter (A–Z), not met
  • A number (0–9), met
  • A symbol, such as ! or #, not met

Your password must have

  • At least 12 characters, met
  • An uppercase letter (A–Z), met
  • A number (0–9), met
  • A symbol, such as ! or #, met

Your password does not meet 3 of the 4 requirements below.

Your password must have

  • At least 12 characters, not met
  • An uppercase letter (A–Z), not met
  • A number (0–9), met
  • A symbol, such as ! or #, not met

Guidance

When to use

  • Show the rules a value must meet before the user types it, and tick them off as they type: a new password, a username, an account or case number with a fixed format.
  • Use it when there are two to six independent requirements the user can fix one at a time.
  • Keep the checklist under its Field and name it in the input's aria-describedby, so screen reader users hear the requirements with the label.
  • Set data-invalid on the checklist after a failed submit, together with the Field's error state, so what is still unmet stands out.

When to consider something else

  • When there is one rule ("Enter a valid email address"), use the Field's helper text and its invalid state; a one-item checklist adds noise. See Field.
  • When the problem is with the whole form or a server check ("That username is taken"), show a Banner or the Field's error after submit. See Banner.
  • When the value is a date split across boxes, use Memorable date and validate the date as a whole. See MemorableDate.
  • When the rules cannot be checked as the user types (they need the server), list them as helper text and validate on submit. See TextField.

Usability

Do
  • Write each requirement as what the value must have ("At least 12 characters"), in the same order every time.
  • Show the checklist before the user starts typing, so the rules are not a surprise.
  • Update the marks as the user types, but let the live region speak only after a pause and only when the count changed.
  • Keep the user's value after a failed submit and mark only what is still unmet.
  • Pair the checklist with a show-password toggle on password fields so users can check what they typed.
Don’t
  • Don't announce each keystroke or each item as it flips; one polite summary is enough.
  • Don't show the list in the error color before the user has submitted; unmet is not an error yet.
  • Don't rely on the check icon or green alone; each item keeps its visually hidden "met" or "not met".
  • Don't disable the submit button until every rule is met; let the user submit and explain what is missing.

Accessibility

Keyboard

No keyboard interaction of its own.

Roles and names

  • The checklist is a ul labelled by its title (aria-labelledby); each requirement is a li.qf-validation__item.
  • Each item ends in a visually hidden .qf-validation__state that says "met" or "not met"; the icons are aria-hidden.
  • The input's aria-describedby names the checklist (after the error message's id when invalid), so its requirements and states are read with the field.
  • There is one live region per checklist, .qf-validation__summary with role="status" (polite, atomic), visually hidden and empty on load.
  • After a failed submit the input carries aria-invalid="true" and the Field shows an error message that says how many requirements are unmet.

Focus

  • Nothing in the checklist takes focus; focus stays in the input while the marks change.
  • On a failed submit, focus moves to the input (or an error summary that links to it).

Other requirements

  • The binding must write the summary after a pause (about one second, as js/docs.js does) and only when the count changed, so screen readers are not flooded (4.1.3).
  • The met check is success-800, 6.26:1 on the page (13.09:1 in dark); the unmet circle is the muted ink; after submit, unmet items are error-700 and bold, 5.22:1 (10.32:1 in dark). Each state is also in text (1.4.1).
  • The checklist reflows with the field at 320px and 400% zoom (1.4.10).
  • Requirements must be stated before input (3.3.2) and the errors described in text (3.3.1, 3.3.3).

Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.

Accessibility tests

WCAG 2.2 AA · Passed

Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.

Validation test checklist
Area Automated A person checks
General Passed Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme.
Zoom Passed At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping.
Keyboard Passed Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order.
Screen reader Passed With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (5 items)

Approving. When the checklist passes on the checked run, record it with bun run a11y:approve -- validation --by "Your name" and commit a11y/approvals.json with the rebuilt pages. All test status

Package

Consumers link one stylesheet, css/classic/index.css, which includes every element. The files below are where this element is defined.

Validation package
Source css/classic/components/validation.css
Specimens also use Box · Card · Chip · Control · Field · Table · Text · Toolbar
Sprites —
React Not yet available: the React binding has not started.

Latest updates

Validation latest updates
Date Version Breaking Description
2026-10-20 0.1 No Validation (C-53), a live requirement checklist under a Field, modeled on the USWDS Validation: a titled list of __item, each data-state="met" or "unmet" with its icon and a visually hidden "met" / "not met", and one polite live region (__summary[role="status"]) that reports the count after the user pauses, never per keystroke. The input names the checklist in aria-describedby; data-invalid after a failed submit turns what is unmet to the error ink. js/docs.js runs the specimen live (components/validation.css)

All release notes