Form Validation

Everyone makes mistakes. When completing a form, users need to know if they made a mistake, where it is, and how to fix it.

The two most common places for error messages are at the top of the form (the “Global” error message) and inline with (beside or below) the fields in error. It is recommended that both be used unless the form is very short.

Placing error messages inline has the advantage that it best supports visual users; it easily identifies which field is in error and, if the error message is sufficiently clear, how to fix it. The disadvantage of using inline error messages alone is that the user must navigate through the entire form to discover the invalid fields and their related error messages. On long or complex forms, this can take some time.

For those longer forms, provide a Global Error Message at the top of the form (after submission). This global error message should include a list of the fields with errors. Each field listed should be linked to its corresponding input, so a user can use the global error message as a way to navigate to the fields they need to correct. Using this global error message as well as inline error messages allows the user to quickly and easily reference how to fix their input.

Placing error messages at the top of the page has the added advantage that, if the validation is server-side and  requires that the entire page reload to show the error, then it is very likely that the user will be looking at the top of the page because that is where users’ eyes naturally go as they see the page refresh.

Complex forms that include tabs and/or grids work very well with this approach. Often forms that are broken up across several tabs or steps have the problem that error messages are not visible until the user clicks on each tab to find those fields in an error state. Forms that use grids benefit from this approach because there is often no room for the error message to be shown inline.

General

The following issues are always required to be addressed to ensure an accessible form validation approach.

Global Error Message

All users should be aware of the presence of errors. At minimum, a live region should provide a message indicating that there are errors. If possible, update the page’s <title> element to indicate there are errors on the page (e.g. change page title from “XXX” to "Form Errors - XXX"). The following image shows an example.


See the Validation Patterns section below for further discussion on when and how to provide this Global Error Message.

Error Message Design

Error messages should always appear along with the fields in error.

Typically, an error message is presented in red text. However, this approach is an example of using colour alone to convey information and violates WCAG Success Criterion 1.4.1 Use of Color.

Add an icon or some other visual aid to distinguish this message from other screen content.

The error message must be placed below the field in error. This best supports mobile users as well as users of screen magnifiers. Users of screen magnifying software might miss an error message if it is placed to the right of the field because they need to scroll to the right of the field to discover it. If the message is underneath the field, it requires less effort to find.

Do not place the error message above the field. Placing the error message above the field causes higher cognitive load for users. It can be easily confused with the label.

Error Message Text

Users just want to get whatever your form requires done. For most users, recent experiences with similar designs will influence their current choices with your design.

Users are best supported when your design is consistent with similar patterns found elsewhere on toronto.ca as well as the larger world wide web. Users may not understand why your form does not like whatever information they have provided. Error messages need to be concise, yet informative.

Users need to know what happened, why it happened, if they can fix it, and how to fix it.

The basic structure of an error message should be in the format: “[The error] [How to fix it]”.

The error message should avoid jargon and use plain language.

For more information on how to write clear error messages, see Error Message Guidelines.

Error Message Accessibility

To be accessible, an error message must be programmatically associated with the field in error using the aria-describedby attribute. This ensures that the screen reader will announce both the field label and the error message.

Programmatically associated error message
<label for="pw">Password</label>
<input type="password" id="pw" aria-describedby="pw_desc">
<span id="pw_desc">Password is missing. Please enter a password.</span>

Note that best practice is to keep the error element (i.e., “pw_desc”) empty and populate it with the error text only when it needs to appear.

If possible, update the page’s <title> element to indicate there are errors on the page (e.g. change page title from “XXX” to "Form Errors - XXX").

Using aria-invalid

In addition to providing a visual means for users to identify and recover from form errors, the aria-invalid attribute must be used to provide this same information programmatically.

The aria-invalid attribute causes screen readers to identify a field as being "invalid" or in need of attention and will assist users as they navigate through a form by focusable elements. All fields that are subject to validation should have aria-invalid="false" by default. This value is changed to "true" (i.e., aria-invalid="true") only after a field has failed validation.

The aria-invalid attribute must be reset back to "false" if the field in question passes validation but other fields are still in error.

An example form pattern can be found at Using aria-invalid to identify failed fields.

Using aria-errormessage

In future, it is expected that accessible forms will be able to use the combination of aria-invalid with aria-errormessage to provide programmatically clear error message functionality without needing to use aria-describedby. This would allow using the aria-describedby property only for providing additional descriptive information about a form element. However, this technique is not (as of summer 2019) supported by all user agents. An example of this approach can be seen in this aria-errormessage CodePen.

Validation Patterns

The City Standard supports three recommended validation patterns:

  1. Real-time inline validation

  2. Validation upon submit (short form)

  3. Validation upon submit (long form)

The Validation upon submit (long form) approach is the most preferred because it supports the most users. Careful consideration must be used to determine the approach that is most appropriate for the design. This section will discuss each of these patterns and their expected behaviour.

Real-time inline validation

Using real-time inline validation is appropriate on short forms. Non-visual users will not be aware of the real-time validation as it occurs. They will only discover that a field is in error if they return focus to the field. For this reason, the real-time inline validation approach should be combined with a Global Error Message when the user activates the “Submit” button.

Error messages should not appear for any field while the user is interacting with it. Unnecessary error validation is annoying and distracts users. The inline validation is triggered only when the user’s focus leaves the field. The following image shows an example.


The required steps for this pattern are:

  1. User interacts with form element and then moves focus to the next element.

  2. Live inline validation is triggered.

  3. If an error is present, a visible, informative, programmatically associated error message appears beneath the form element in error.

  4. If the user returns to the form element in error:

    1. Form element label and programmatically associated error message is announced on focus.

    2. After user interacts with the form element and moves focus away again, old error message is removed

    3. Live inline validation is re-triggered (see Step 3).

  5. Client-side validation is triggered on activation of the Submit button.

    1. If errors are present:

      • Global Error Message (with role="alert") appears at the top of the form

        • e.g., "There are errors in your form"

      • Visible, informative, programmatically associated error message(s) appears beneath each form element in error.

      • Focus is set to first field with an error.

Validation upon submit (short form)

This approach can be used on short forms that do not use real-time inline validation.

The required steps for this pattern are:

  1. User interacts with form elements.

  2. User activates Submit button.

    1. Client-side validation is triggered.

    2. If errors are present:

      • Global Error Message (with role="alert") appears at the top of the form

        • e.g., "There are errors in your form"

      • Visible, informative, programmatically associated error message(s) appears beneath each form element in error.

      • Focus is set to first field with an error.

Validation upon submit (long form)

This approach must be used on long and/or complex forms and can be used on any forms. This approach is the most preferred because it supports the most users.

This approach updates the Global Error Message to also include a list of all errors in the form. This entire message will appear above the form. The following image shows an example.


  • Each error listed should be an in-page link to its respective input in error, allowing users to jump directly to the field to correct the error.

    •  Activating the link should move focus to the field in error.

  • The Global Error Message should include a heading that:

    • Appropriately follows the page’s heading hierarchy

    • Indicates there are errors present.

    • Receives Focus programmatically on page refresh (or view update, for single page applications).  The heading should have tabindex=”-1” so it can receive focus. 

  • Users should be aware of how many errors there are.

  • Visible, informative, programmatically associated error message(s) should also appear beneath each form element in error.

For more information about this approach, see the Error Message List section of Resources below.

The required steps for this pattern are:

  1. User interacts with form elements.

  2. User activates Submit button.

    1. Client-side validation is triggered.

    2. If errors are present:

      • Global Error Message, including a list of links to each form element in error, appears at the top of the form.

      • Message does not have role="alert".

      • Focus is set to the Global Error Message heading. Ensure message is announced.

        • e.g., "There are XXX errors in your form."

Resources

Crafting Error Messages:

Accessible Validation:

Error Message List: