Form Validation
To avoid users making errors during form submission keep the following in mind:
Built-in constraints on Inputs
Where appropriate, allow only certain kinds of input, such as only numerals
when typing a zip code. To restrict the options even further, pre-define
them as data values in <select>
lists, radio buttons, checkboxes,
or some other fixed format.
Step-by-Step views
When there are diverging paths through an interaction, it's usually not a good idea to show all possibilities at the same time. It can be confusing for users, and difficult in terms of the programming logic to ensure that all possibilities and error states are taken into account. Allow users to make a choice, then show the resulting set of choices for that path only.
Visual design that focuses user attention
Ensure labels and instructions are near their respective inputs. Reduce distractions in the visual design. Use visual cues to guide users to fill out the form properly. Make error messages and confirmation messages visually obvious.
Confirmation prior to submitting
Summarize what will happen when the user submits the form, BEFORE the form is submitted. Ask the user to verify that the information is correct. This is especially important when actions are irreversible.
Confirmation after submitting
Summarize the result on the screen after the form is submitted, to let users review their action once again.
Aim for inline validation whenever possible
Ideally, all validation should be inline: that is, as soon as the user has finished filling in a field, an indicator should appear nearby if the field contains an error. This type of error message is easily noticeable; moreover, fixing the error immediately after the field has been completed requires the least interaction cost for users: they don’t need to locate it or navigate to the field, nor do they have to switch context from a new field to return to an old field they thought they had completed successfully.
Of course, there will be situations where inline validation won’t be possible and data entered by the user will need to be sent to a server for verification.
Implementation Details
- Set invalid fields to
aria-invalid="true"
- Move focus to error/success message
-
Ensure error/success message container is set to
tabindex="-1"
. Otherwise, focus cannot be set successfully. - Provide a count of errors so that users get a sense of the scope of the problem.
-
Ensure error messages are associated with form fields using
aria-describedby
so that screen reader users know how to fix the problem - Ensure error messages are visible so that sighted users know how to fix the problems
- Ensure error messages are adjacent to the inputs so that screen magnification users can easily see which messages belong to which fields.
Error Messaging
Use the .invlaid-feedback
class to display error messages. You
can toggle display properities to hide and show error messaging.
<form class="row g-4 needs-validation" novalidate>
<div class="col-md-4">
<label class="form-label" for="validationCustom01">First name</label>
<input class="form-control" id="validationCustom01" type="text" required />
<div class="invalid-feedback d-block">Please provide your first name.</div>
</div>
<div class="col-md-4">
<label class="form-label" for="validationCustom02">Last name</label>
<input class="form-control" id="validationCustom02" type="text" required />
<div class="invalid-feedback d-block">Please provide your last name.</div>
</div>
<div class="col-md-4">
<label class="form-label" for="validationCustomUsername">Username</label>
<div class="input-group has-validation">
<input
class="form-control"
id="validationCustomUsername"
type="text"
aria-describedby="inputGroupPrepend"
required />
<div class="invalid-feedback d-block">Please choose a username.</div>
</div>
</div>
<div class="col-md-6">
<label class="form-label" for="validationCustom03">City</label>
<input class="form-control" id="validationCustom03" type="text" required />
<div class="invalid-feedback d-block">Please provide a valid city.</div>
</div>
<div class="col-md-3">
<label class="form-label" for="validationCustom04">State</label>
<select class="form-select" id="validationCustom04" required>
<option value="" selected disabled>Choose...</option>
<option>...</option>
</select>
<div class="invalid-feedback d-block">Please select a valid state.</div>
</div>
<div class="col-md-3">
<label class="form-label" for="validationCustom05">Zip</label>
<input class="form-control" id="validationCustom05" type="text" required />
<div class="invalid-feedback d-block d-block">
Please provide a valid zip.
</div>
</div>
<div class="col-12">
<div class="form-check">
<input
class="form-check-input"
id="invalidCheck"
type="checkbox"
value=""
required />
<label class="form-check-label" for="invalidCheck">
Agree to terms and conditions</label
>
<div class="invalid-feedback d-block">
You must agree before submitting.
</div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
Modal Error Message
Ensure that focus moves back to the first invalid form field when the modal is closed.
If the form submission causes a new page to load (or the same page to reload)
Ensure the page <title>
reflects the error or success confirmation
status.
The title could say something like, "There were 3 errors in the form" or
"Success! Your account has been created." The page <title>
is the first thing screen reader users hear when the page loads, so it is the
fastest way to give them feedback on the form submission status.
Provide a quick way to reach the status message.
Some options include:
- Provide a "skip to main content" link that takes the users to the message.
-
Move the focus to the confirmation message after the page loads.
IMPORTANT: You will need to let the page finish loading, then set a JavaScript timeout of 1 to 2 seconds to allow the screen reader virtual buffer to process the page, then use JavaScript to send the focus to the confirmation message. If you send the focus to the message immediately upon page load, the focus may be set successfully, but screen readers will say nothing because they haven't had time to determine what is on the page.