Skip to content

Forms

Layout, validation, errors and submission — the rules that make forms fast to complete and hard to get wrong.

Forms are where products ask people for effort. Every rule below exists to reduce that effort: fewer decisions, clearer errors, no lost work.

Layout

  • One column. Multi-column forms break the reading path and hide fields. The exception is short, related pairs — first and last name, expiry and CVC.
  • Labels above fields. Top-aligned labels are the fastest to scan and survive translation and zoom. Use FieldLabel, never a placeholder, as the label.
  • Group with FieldSet. Related fields share a FieldLegend; groups are separated by more space than fields within them.
  • Size the field to the answer. A postcode field shouldn't be as wide as an address field.
  • Horizontal rows for settings. Settings pages pair a label and description on the left with the control on the right, using Field orientation="responsive" so it stacks on narrow screens.
Project settings
Changes apply to new deployments.

Required and optional

Mark the minority. Most forms should only ask for what's required — then label the few optional fields with “(optional)” and don't decorate required ones. When most fields are optional, mark the required ones instead. Never rely on an asterisk alone; it means nothing to many people and to screen readers.

Validation

When to validate

  1. On submit, validate everything and move focus to an error summary at the top of the form.
  2. After the first submit, re-validate a field when people leave it (blur) so errors disappear as soon as they're fixed.
  3. Never on every keystroke before a submit — being told an email is invalid after typing one letter is hostile.

How to show errors

  • Put the message directly under the field with FieldError, which renders an icon and text — never color alone.
  • Mark the control with aria-invalid and the field with data-invalid.
  • Say what's wrong and how to fix it: Enter an email address like ada@acme.co, not Invalid input.
  • For forms longer than one screen, add an Alert summary that lists the problems and receives focus.
<Field data-invalid>
  <FieldLabel htmlFor="email">Work email</FieldLabel>
  <Input id="email" aria-invalid />
  <FieldError>Enter an email address like ada@acme.co.</FieldError>
</Field>

Submission

  • Keep the submit button enabled. A disabled button can't explain what's missing; submitting and showing errors can.
  • Show progress on the button with loading. It keeps its width and focus, and blocks double submission.
  • Confirm success with a toast when people stay on the page, or navigate to the result.
  • Never clear the form on error. Server errors are shown inline or in a summary, and every value is preserved.
Do.Specific guidance next to the field, with an icon.
Don’t.A red border alone fails people who can't see the color — and explains nothing.

Accessibility checklist

  • Every control has a programmatic label (htmlFor + id, or aria-label for icon-only controls).
  • Help text is linked with aria-describedby; errors are announced (FieldError uses role="alert").
  • autocomplete attributes are set for personal data (name, email, new-password), so browsers and password managers can help.
  • The form is fully operable with the keyboard, in a logical order, with visible focus.