Field

Gives an input its label and error.

Orientation

  • It appears in run IDs.

    verticaldefault

  • horizontal

States

  • rest

  • Shown in run IDs.

    described

  • No spaces.

    invalid

  • Locked during a run.

    disabled

Usage

When to use it
Use
Any Input, Textarea, Checkbox, Switch or Slider that a person fills in or sets.
Use
Several related questions share one title (FieldSet and FieldLegend).
Use
A set of fields is submitted together and checked together (Form).
Not for
A search box that filters the page, labelled by the page itself: give the Input aria-label.
Not for
A value to read, not to change: show it as text, or Input mode="copy".

Rules

9 rules
Must
Put exactly one control in a Field; group several with FieldSet. Because Base UI binds the label, the description and the error to one control, so a second control is named by the first one's label.
Never
Let a placeholder stand in for FieldLabel. Because a placeholder vanishes on the first keystroke, is 3.3:1 grey and is not a reliable accessible name.
Must
Say in FieldError what is wrong with this value and how to fix it, in one sentence. Because the coral line only says something is wrong; the sentence is what a screen reader hears and what the person acts on.
Must
Validate through the Field (validate, invalid or the control's constraints), never with your own onChange check. Because Field waits for blur before it shows an error and then clears it on the keystroke that fixes it, and a hand check shows coral on the first letter.
Never
Mark a required field with a red or coral asterisk; pass required or optional to FieldLabel. Because coral means something went wrong in Glaze, and an asterisk is a symbol a screen reader may skip.
Should
Mark whichever kind is rarer in the form: optional when most fields are required, required when most are optional. Because a word on every label is noise, and the few marked ones stand out.
Must
Route server errors back through Form errors by field name, and announce the result in FormStatus. Because Form focuses the first invalid field and Base UI ties the message to it, where a toast leaves the person hunting for the field.
Should
Use orientation="horizontal" with FieldContent for a switch or a checkbox beside its label and description.
Should
Keep FieldDescription to one or two lines about the value's use or shape; put policy in the page, not under a field.

State order

4 states, highest first
1
disabled
2
invalid
3
described
4
rest

Accessibility

6 checks
FieldLabel is a <label> bound to the control; FieldDescription and FieldError join its aria-describedby.
FieldError appears when the field is invalid and is read with the control on focus; the control gets aria-invalid.
FieldSet is a <fieldset> named by its <legend>, so each control inside is announced with the set's title.
Form focuses the first invalid field on submit; FormStatus is role="status", rendered from the start so its change is heard.
Required and optional are words, not symbols, so a screen reader reads them with the label.
Description text is text-2, 5.5:1 on paper; the error word is --fail-text, 5.9:1.

Keyboard

2 keys
Tab
Moves from field to field; the label and description are not stops.
Enter
In a text field, submits the Form.

Edge cases

7 edge cases
Error longer than the field
Wraps under the control up to the 60ch hint measure.
Several schema errors
Duplicates drop and the rest become a list.
Field inside a Field
Development builds warn; the inner control would take the outer label.
Description outside a Field
Renders a plain paragraph, so it works under a FieldLegend.
Disabled FieldSet
Every label, description and control inside goes to the disabled text colour.
Phone width
A responsive field stacks its label above the control.
Submit twice while pending
Form drops the second submit, Enter in a field included.

API

9 props
Field orientation
'vertical' | 'horizontal' | 'responsive' default 'vertical'
Field validate, invalid, name
Base UI Field
Field validationMode
'onBlur' | 'onChange' | 'onSubmit'
FieldLabel required, optional
boolean default false
FieldError errors
Array<{message?: string}>
FieldSet disabled
boolean default false
FieldLegend variant
'legend' | 'label' default 'legend'
Form pending, errors, onFormSubmit
boolean, Record<string, string>, (values) => void
FormStatus status
'ok' | 'fail'

Tokens

14 tokens
--text-1
rgb(5 5 5 / 0.80)
--text-2
rgb(5 5 5 / 0.60)
--text-disabled
rgb(5 5 5 / 0.32)
--fail-text
#b23c29
--ok-text
#1a7640
--line
rgb(5 5 5 / 0.10)
--type-label
500 13px/1.35 var(--font-sans)
--type-body-sm
400 13px/1.5 var(--font-sans)
--type-heading-sm
500 16px/1.35 var(--font-sans)
--type-caption
400 12px/1.35 var(--font-sans)
--measure-hint
60ch
--label-col
160px
--space-4
16px
--space-6
24px

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.