Skip to main content

Handling Errors in Accessible Forms

Accessible forms is not just about ensuring they can be used by everyone but also about providing clear, accessible feedback when users make mistakes


Handling Errors in Accessible Forms

Shawn Sandy (Ally.Cafe) ~


Creating accessible forms is not just about ensuring they can be used by everyone but also about providing clear, accessible feedback when users make mistakes. Proper error handling is crucial in helping users understand what went wrong and how to fix it. Below are the WCAG 2.2 guidelines related to error handling in forms, along with best practices and code examples.

Key WCAG 2.2 Guidelines for Error Handling

3.3.1 Error Identification

Level A
If an input error is detected, the error should be identified and described to the user in text.

Example:

<form id="signup-form">
  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required aria-required="true">
  <span id="email-error" class="error" aria-live="polite"></span>
  
  <button type="submit">Sign Up</button>
</form>

<script>
  document.getElementById('signup-form').addEventListener('submit', function(event) {
    var emailInput = document.getElementById('email');
    var emailError = document.getElementById('email-error');
    
    if (!emailInput.checkValidity()) {
      event.preventDefault();
      emailError.textContent = 'Please enter a valid email address.';
    } else {
      emailError.textContent = '';
    }
  });
</script>

3.3.2 Labels or Instructions

Level A
Labels or instructions should be provided when user input is required.

Example:

<form>
  <label for="username">Username:</label>
  <input type="text" id="username" name="username" required aria-required="true">
  <span id="username-instructions" class="instructions">Username must be between 4 and 12 characters.</span>
</form>

3.3.3 Error Suggestion

Level AA
If an input error is detected and suggestions for correction are known, then the suggestions are provided to the user.

Example:

<form id="contact-form">
  <label for="phone">Phone:</label>
  <input type="tel" id="phone" name="phone" required aria-required="true">
  <span id="phone-error" class="error" aria-live="polite"></span>
  
  <button type="submit">Submit</button>
</form>

<script>
  document.getElementById('contact-form').addEventListener('submit', function(event) {
    var phoneInput = document.getElementById('phone');
    var phoneError = document.getElementById('phone-error');
    
    if (!phoneInput.value.match(/^\d{10}$/)) {
      event.preventDefault();
      phoneError.textContent = 'Please enter a valid 10-digit phone number.';
    } else {
      phoneError.textContent = '';
    }
  });
</script>

Level AA
For forms that cause legal commitments, financial transactions, or data modifications, users should be able to review, correct, and confirm their input before finalizing the submission.

Example:

<form id="checkout-form">
  <label for="credit-card">Credit Card Number:</label>
  <input type="text" id="credit-card" name="credit-card" required aria-required="true">
  <span id="credit-card-error" class="error" aria-live="polite"></span>
  
  <button type="button" onclick="reviewOrder()">Review Order</button>
</form>

<div id="review-section" style="display: none;">
  <p id="order-details">Order details...</p>
  <button type="submit" form="checkout-form">Confirm Order</button>
  <button type="button" onclick="editOrder()">Edit Order</button>
</div>

<script>
  function reviewOrder() {
    var creditCardInput = document.getElementById('credit-card');
    var creditCardError = document.getElementById('credit-card-error');
    
    if (!creditCardInput.value.match(/^\d{16}$/)) {
      creditCardError.textContent = 'Please enter a valid 16-digit credit card number.';
    } else {
      creditCardError.textContent = '';
      document.getElementById('checkout-form').style.display = 'none';
      document.getElementById('review-section').style.display = 'block';
    }
  }

  function editOrder() {
    document.getElementById('review-section').style.display = 'none';
    document.getElementById('checkout-form').style.display = 'block';
  }
</script>

Best Practices for Error Handling

  1. Use Clear, Simple Language: Error messages should be easy to understand, avoiding technical jargon.
  2. Real-Time Validation: Provide real-time feedback to users as they fill out the form to prevent errors before submission.
  3. Accessible Error Messaging: Use ARIA live regions to ensure that error messages are announced to screen reader users.
  4. Focus Management: Move focus to the first error message when a form is submitted with errors, ensuring users are immediately aware of the issues.
  5. Consistent Placement: Place error messages close to the form fields they relate to, ensuring users do not need to search for the error descriptions.

Code Example

Here is a complete example of a form with accessible error handling:

<form id="registration-form">
  <fieldset>
    <legend>Register</legend>
    
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required aria-required="true">
    <span id="email-error" class="error" aria-live="polite"></span>
    
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" required aria-required="true">
    <span id="password-error" class="error" aria-live="polite"></span>
    
    <button type="submit">Register</button>
  </fieldset>
</form>

<script>
  document.getElementById('registration-form').addEventListener('submit', function(event) {
    var emailInput = document.getElementById('email');
    var emailError = document.getElementById('email-error');
    var passwordInput = document.getElementById('password');
    var passwordError = document.getElementById('password-error');
    
    var valid = true;
    
    if (!emailInput.checkValidity()) {
      emailError.textContent = 'Please enter a valid email address.';
      valid = false;
    } else {
      emailError.textContent = '';
    }
    
    if (passwordInput.value.length < 6) {
      passwordError.textContent = 'Password must be at least 6 characters long.';
      valid = false;
    } else {
      passwordError.textContent = '';
    }
    
    if (!valid) {
      event.preventDefault();
    }
  });
</script>

Useful Resources

For more information on accessible error handling in forms, refer to the following resources:

  1. WAI Tutorial: Form Validation
  2. WebAIM: Form Validation
  3. MDN Web Docs: Using the alert role

By following these guidelines and best practices, you can ensure that your forms provide clear, accessible feedback, helping all users successfully complete their interactions.


Found an error, typo, or bug please edit on github or open an issue or ticket