Form guidelines
Optional and required labels
We only ask for information we need. Unless labelled otherwise, all fields in a form are required.
Mark optional fields with "(optional)".
☝️ Research insight: We follow the [GOV.UK guidance on forms](https://design-system.service.gov.uk/patterns/question-pages/).
Labels and legends as headings
When asking just one question on a screen, page heading will then most likely be the same as the label
or legend
for the input. To avoid repetition, you can set the label
or legend
as the page heading.
Form validation principles
Form feedback notifies users that the form they're trying to submit has errors. It includes field validation and form validation.
We use on blur validation only for fields that are:
- required
- have an expected valid format
- have been attempted to complete by the user
In all other cases form validates on submission.
No field validation on blur if no input has been entered
A1. The first (required) field is focused, showing the blue focus style.
A2. If the user hasn't entered input and clicked a different field, the first field is not validated on blur.
Form and field validation on submit
A3. The other fields are filled out correctly (a valid format is used). So, when the user focuses on the submit button, they have already successfully validated.
A4. When the submit button is pressed, there are errors in the form. The form validation message (inserted in an ARIA live region) is shown, as well as the field validation.
This alerts sighted and blind users to move back up the form to fix the errors.
Field validation on blur after input entered
B1. If the user typed something in the filed but hasn't entered valid input, the field is blurred and the error style and message appears.
aria-invalid="true"
is applied to the input, and the error message is associated with the input's id
using aria-describedby="[the id]"
.
The user could go back up straight away to fix the field, but in this case continues to fill out the second field which is now focused.
B2. The other fields are filled out. So, when the user focuses the submit button, they have already successfully validated.
Form validation and fixing the errors
B3. When the submit button is pressed, there are errors in the form. The form validation message (inserted in an ARIA live region) is shown, as well as the field validation.
This alerts sighted and blind users to move back up the form to fix the errors.
B4.
The user moves focus up through the valid fields (which will be announced in screen readers as valid due to aria-invalid="false"
) and focuses the first, invalid field. The focus style overrides the error style.
Multiple errors
C1. When the submit button is pressed, there are errors in the form. The form validation message (inserted in an ARIA live region) is shown, as well as the field validation for all invalid fields.
This alerts sighted and blind users to move back up the form to fix the errors.
C2.
When there are multiple errors the user moves focus up through the valid fields (which will be announced in screen readers as valid due to aria-invalid="false"
) and focuses on the invalid fields, one by one. The focus style in the focussed field overrides the error style. The error styles in other fields remain.
Adding form validation
Form validation uses a live region to make it accessible to screen reader users (the error message is announced).
☝️ Research insight: The Bulb website underwent usability testing with users with screen-readers, and found that screenreader users expect error states to be present below the last element they interacted with. Ensure that error messages read directly below the input or button so that users with screen-readers can encounter the error message.
The show
prop
You pass a boolean from the parent component to show
to determine whether the error message should be triggered. This would normally be in response to the user trying to submit the form.
The message
prop
This simply defines the message that will be shown and announced in screen readers. Something generic is recommended since each invalid field should have its own error message.