Skip to main content
Pricing

Forms

Forms are the primary way users input data. A well-structured form reduces cognitive load, prevents errors, and guides users toward successful submission. This pattern covers layout, validation, field grouping, and multi-step flows.

Components used

Anatomy

1
Form wrapper vertical Stack with 24px gap between fields
2
Form Field label (top) + input + helper text / error message (below)
3
Field groups related fields wrapped with a Heading and Divider separator
4
Error Summary appears above the form when submission fails, links to each invalid field
5
Action bar right-aligned primary Button, optional secondary Cancel as link or tertiary button

Best practices

Layout

Use a single-column layout for most forms — it reduces eye movement and works across all screen sizes. Place labels above inputs, not beside them. Group related fields with a section heading and divider.

Validation

Validate on blur for individual fields and on submit for the full form. Show inline errors below each field with aria-describedby linking the error to the input. When submission fails, show an Error Summary at the top of the form with anchor links to each invalid field.

Required fields

Mark required fields with a visual asterisk (*) in the label and aria-required="true" on the input. If most fields are required, mark optional fields instead — "Email (optional)".

Progressive disclosure

Only show fields when they become relevant. For example, show "Company name" only when the user selects "Business" as account type. This reduces initial cognitive load.

Multi-step forms

Use Stepper to show progress across steps. Validate each step before allowing progression. Allow users to navigate back to previous steps without losing data. Show a summary before final submission.

Button placement

Place the primary action button (Submit, Save) right-aligned at the bottom of the form. Place Cancel as a link or tertiary button to the left. Never use "Reset" — it destroys user work without confirmation.

Responsive behaviour

Forms remain single-column on all screen sizes — no side-by-side fields on mobile.
Button bar stacks vertically on mobile with primary button on top.
Date Picker and Select panels become full-width bottom sheets on mobile.
Error Summary becomes a sticky banner at the top of the viewport on mobile.

Accessibility

Every input must have a visible label associated via htmlFor/id or wrapping <label>.
Error messages use aria-describedby to link the error text to the input, and aria-invalid="true" on the field.
Error Summary uses role="alert" and receives focus when it appears so screen readers announce it immediately.
Required fields use aria-required="true" — the visual asterisk alone is not sufficient.
Form submission must be possible via keyboard alone — Tab through fields, Enter to submit.
Disabled fields retain visible labels and use aria-disabled="true" with a tooltip explaining why.