Input

Inspect

Examples

Input fields

Inspect

Input sizes

Inspect

Disabled state

Inspect

Required and optional

Mark the required side with a Required badge on the label, and say "Optional" in a FieldDescription — never an asterisk, which carries no meaning to a screen reader on its own. Pick one per form and stay with it: if most fields are required, label the few optional ones instead of badging everything.

required on the control itself is separate — it drives native validation and aria-required, and should be set whether or not the badge is shown.

Inspect

Optional — for business invoices.

Invalid state

aria-invalid paints the halo on the control. The message itself is a FieldError, which tucks behind the control so the two read as one shape — never an InlinePrompt, which is a standalone status pill, not field validation.

Inspect

Valid state

The mirror of the invalid state, in green. data-valid is a data attribute rather than an ARIA one because ARIA has no affirmative counterpart to aria-invalid — there is nothing to announce until there is a message to announce.

It comes at two volumes, and the quiet one is the default. data-valid="quiet" is a tick at the trailing edge of the control and nothing else: no halo, no border, no panel, no reflow. Several fields can carry it at once without the form reading as a wall of green, which is exactly what makes it the one to reach for after a format check or a lookup that simply came back fine.

Inspect

data-valid="true" is the loud one: the full halo, plus a FieldSuccess that tucks behind the control the way a FieldError does and announces politely (role="status"). Spend it on the one answer worth a sentence — username free, code accepted, address found. Spend it twice on the same form and you have spent it nowhere, and a wall of green is as hard to scan as a wall of red.

Inspect
That username is available.

On this page