Under Construction: The content on this site draft material. It is not the official content of this site and should not be followed at this time.

Not Legal Advice: The content on this site is provided for informational purposes only and does not constitute legal advice. Consult a qualified attorney for advice specific to your situation.

Purpose

Accessible form validation ensures that users of all abilities understand which fields have errors, what the error is, and how to correct it—without relying solely on color.

Usage Guidance

  • Display errors inline, adjacent to the field
  • Summarize all errors at the top of the form for long forms
  • Never use color alone to indicate errors
  • Show errors after user interaction (not on page load for required fields)
  • Provide corrective guidance, not just “Field is invalid”

Accessibility Considerations

  • Associate error messages with fields using aria-describedby
  • Mark invalid fields with aria-invalid="true"
  • Use role="alert" on dynamically injected error summaries
  • Use aria-live="polite" for inline errors that appear after validation

Keyboard Support

Form validation follows standard form keyboard behavior. After validation, move focus to the first invalid field or the error summary.

Screen Reader Behavior

When aria-invalid="true" is set, screen readers announce “invalid entry” when focusing the field. aria-describedby ensures the error message is read when the field receives focus.

ARIA Requirements

  • aria-invalid="true" on invalid fields
  • aria-describedby="error-id" on each invalid field, referencing its error message
  • role="alert" on dynamically injected error summaries

Common Mistakes

  • Using only red border/text color to indicate errors
  • Not associating error text with the field via aria-describedby
  • Not setting aria-invalid="true" on the field
  • Moving focus to an error summary without giving it tabindex="-1" first

Live Example


Code Example

<div class="form-group">
  <label for="email">
    Email Address
    <span aria-hidden="true">*</span>
    <span class="visually-hidden">(required)</span>
  </label>
  <input
    id="email"
    type="email"
    aria-required="true"
    aria-invalid="false"
    aria-describedby="email-error"
  >
  <p id="email-error" role="alert" hidden>
    Please enter a valid email address (e.g., name@example.com).
  </p>
</div>
function validateField(input) {
  var isValid = input.checkValidity();
  var errorEl = document.getElementById(input.getAttribute('aria-describedby'));
  input.setAttribute('aria-invalid', String(!isValid));
  errorEl.hidden = isValid;
}