Provide helpful error messages

People with visual, cognitive and physical impairments are particularly prone to making errors when entering data through forms. When errors resulting from form input happen, it’s important to make sure that error messages are shown accessibly.

  • Provide error messages that give assistance: Describe the related problem in straightforward terms and, where possible, give advice on how to resolve them.
  • Make it easy to locate the problem: Programmatically associate each error message with its corresponding form control using the aria-describedby attribute. If there’s a list of errors, move focus to the container of the list once it is generated so that screen reader users can find it. 

Testing

For each input control where an error could be made, enter incorrect data and check:

  • Is an error message displayed?
  • Does it clearly explain the error and how to resolve it?
  • When a screen reader is running, is it possible to find the location of the error message and the associated form control?

Resources

✎ Technique: Form error communication

Effectively and accessibly communicate form errors by:

  1. Communicating that a form has errors,
  2. Communicating any individual errors case by case, including clear guidance on how to address the error.

In part, this involves thoughtful content-writing to clearly and unambiguously help users recover from the error. But it also requires that error messages are made clear to screen-reader users, who may not otherwise be aware of them. This can be achieved by incorporating a WAI-ARIA live region into the form design and using the aria-describedby relationship attribute and the aria-invalid state attribute.

Example

This example of a user registration form contains three fields within a <fieldset> that are labeled "Your email," "Choose a username," and "Choose a password:"


<form>
  <fieldset>
    <legend>Register</legend>
    <label for="email">Your email</label>
    <input type="text" id="email">
    <label for="username">Choose a username</label>
    <input type="text" id="username">
    <label for="password">Choose a password</label>
    <input type="password" id="password">
  </fieldset>
  <div class="submit">
    <button type="submit">Submit</button>
  </div>
</form>

In the adapted code below, we add an empty live region just above the submit button, which can be used to report to screen reader users if there are any errors when the user tries to submit the form. In addition, each field is followed by a "hint" that is hidden by default but shown if that field does not validate:


<form>
  <fieldset>
    <legend>Register</legend>
    <label for="email">Your email</label>
    <input type="text" id="email">
    <div class="hint" id="emailHint" style="display: none">Please enter a valid email</div>
    <label for="username">Choose a username</label>
    <input type="text" id="username">
    <div class="hint" id="usernameHint" style="display: none">Your username cannot contain punctuation</div>
    <label for="password">Choose a password</label>
    <input type="password" id="password">
    <div class="hint" id="passwordHint" style="display: none">Your password must be at least 6 characters</div>
  </fieldset>
  <div aria-live="assertive" id="message">
  </div>
  <div class="submit">
    <button type="submit">Submit</button>
  </div>
</form>

If the form is submitted and there are errors, two things happen. First, the live region is populated, announcing to screen-reader users that there are errors they must attend to:


$('[aria-live="assertive"]').append('<p>Your form has errors. Please fix them and submit again.</p>');

Note that this is achieved without moving the user's focus. Having traversed the form, they know that they are below the inputs and can use SHIFT+TAB to go back to the invalid fields.

Second, each invalid input is given aria-invalid="true" and connected to a "hint" using aria-describedby. This provides two pieces of information to screen-reader users when they focus the input:

  1. That the information they entered is invalid
  2. An explanation of why the information is invalid. The "hint" element is also revealed visually for those seeing the form.

Here's the markup for the email field in its invalid state:

<label for="email">Your email</label>
<input type="text" id="email" aria-invalid="true" aria-describedby="emailHint">
<div class="hint" id="emailHint" style="">Please enter a valid email.</div>

 

Note that the aria-descibedby hint connects to the input in the same way as the label, using its id. Now, when the email field receives focus, the VoiceOver screen reader announces, "your email, invalid data, text [pause] please enter a correct email." Because screen reader users interact with forms by keyboard, moving directly between inputs, it's important that all this information is conveyed on focus.

Video: Form error handling with Safari and Voiceover

 

Form error handling with Safari and Voiceover

 

Code editor

You can experiment with and repurpose this implementation through the "Form error handling with ARIA" online code editor.

✎ Technique: Form feedback with live regions

Providing form feedback accessibly helps users submit data more accurately and reduces the chance for error. For learning resources, easy access to feedback supports the learning process; for forms collecting data, good feedback helps to reduce the chance of input errors being made. 

When providing feedback on user input, JavaScript is often employed to print messages to the screen. Users looking at the screen will see the message appear in response to their actions. Screen-reader users who do not have access to visual changes need to be notified of the feedback so they can have an opportunity to read it and act on it.

WAI-ARIA live regions can be used for this. Adding content inside a live region tells assistive technologies to announce the content to the user—without users having to move to that part of the page.

Example

In this example, the user is presented with a multiple choice quiz question: "Who's the biggest selling recording artist?" When they click the "check answer" button, a message provides feedback on their answer. The markup looks like this:


<form>
  <fieldset>
    <legend>Who's the biggest selling recording artist?</legend>
    <div>
      <label><input type="radio" name="answer" value="michael"> Michael Jackson</label>
      <label><input type="radio" name="answer" value="elvis"> Elvis Presley</label>
      <label><input type="radio" name="answer" value="iggy"> Iggy Pop</label>
      <label><input type="radio" name="answer" value="madonna"> Madonna</label>
    </div>
  </fieldset>
  <div aria-live="polite">
  </div>
  <div class="buttons">
    <button type="button" class="check">check answer</button>
    <button type="submit" disabled>next question</button>
  </div>
</form>

Note the empty <div> with the aria-live="polite" attribute. This is our live region. When we add content inside it (text or HTML elements containing text), screen readers will announce that content.

For instance, if the user activates the "check answer" button without having chosen an answer, the live region will be populated with the message, "Please choose an answer." This message appears to sighted users as a highlighted box, and it’s heard as speech by an assistive-technology user.


$('[aria-live="polite"]').append('<p>'+message+'</p>');

If, upon pressing "check answer," the user has the correct answer checked, the message congratulates them. In addition, the "next question" button is enabled (by removing the disabled attribute) and focused.


$('[type="submit"]')
        .removeAttr('disabled')
        .focus();

Using the screen reader NVDA with Firefox, this produces the screen reader speech output, "Elvis is correct! You can go to the next question, next question button." That is, the live region is announced, and then the newly focused element is announced. Three important pieces of information are provided: The user has chosen correctly, they can continue, and the button currently in focus will allow them to continue. Had we used an aria-live value of assertive, the live region's message would have overridden the focus change and "next question button" would not have been announced.

Video: Form feedback with NVDA using a live region

 

Video: Form feedback with NVDA using a live region

 

Code editor

An editor is available to try out the preceding live region example. Experiment by removing the live region and try operating it with just the keyboard, with your eyes closed.