These conventions are intended to provide guidance for both layout and proper usage of various form elements.
Designing an effective form requires consideration for its information hierarchy, sequence of form elements, clarity of labels, affordance, feedback, and accessibility.
Form layouts organize input fields for our users to enter data and configure options. A form layout should be easy to scan, understand and complete.
Typically, forms should be one column. Multiple columns can be disruptive to a user’s vertical momentum. However, related fields are sometimes represented as a group on a single row when a mental model suggests they be treated as a singular concept. For example, city, state, and zip might be considered an “address”.
Use to handle most aspects of a form’s layout.
Form fields that are related should be grouped together and labeled.
- Use to make sure your grouping is formatted and labeled properly.
- If necessary, provide a concise description of what’s represented in each section.
- Radio buttons and checkboxes should be grouped using a as well.
- If does not work for your use case you can use
<legend>, but note that you’ll probably have to override the default styles.
Labeling form fields
All form fields should be labeled to help users fill out the form and take the appropriate action.
- It’s prefered that all form fields have a visible label.
- Use , which will add the label association for you. Or use , making sure to associate the label with the form field using .
- If there isn’t enough space for a visual label you can use an
aria-labelon the field instead.
If your labels are properly associated, clicking on the label for a form element should focus the input field.
Optional vs. required fields
Inputs in a form should be required by default. Be mindful when requesting optional information. Added inputs increase cognitive load and the perceived effort required to complete a task. If you must ask a user for optional information, then denote it as “optional” in it’s label.
The length of the text field affords the length of the answer expected. Employ this for text fields that have a defined character count like phone numbers, zip codes, etc.
Is used to provide additional guidance with a form field. Helper text is added via the prop.
Helper text should be:
- Meaningful and concise
- Sentence case
Checkboxes & radio buttons
Always align checkboxes and radio buttons vertically and group them with a .
Most forms should have a submit button. Use
secondary for a main call to action and
default for a secondary action. Always use a descriptive call to action.
Asynchronous inputs should mostly be avoided. Use your best judgment when deciding whether or not your specific needs warrant one. Be sure to provide users with clear feedback about the state of the input and submission.
Validation and errors
Validation should occur on submission of the form.
Real-time validation can be messy and distracting for the user. Only use real-time validation in scenarios where errors can be easily prevented. For example, a character counter for an input with character limit.
A form error should be associated with the input that’s causing the error. The component does this for you, but if you have to roll your own, make sure to use
aria-describedby on the input to point to the id of the error.