Helpful Error Messages
When someone makes a mistake in your form, don’t leave them guessing.
Too often, forms highlight errors with a red border and a vague message like “Invalid input.” That’s not helpful, especially for users with cognitive impairments or those using assistive technologies like screen readers.
Good error messages should:
- clearly state what went wrong
- tell the user how to fix it
- appear next to the related field
- be programmatically tied to that field
- be announced automatically
Good Practice
- Place error messages immediately after or near the field they refer to
- Use plain, specific language. For example: “Please enter your email address” instead of “Invalid”
- Tie errors to fields using
aria-describedbyoraria-errormessage - Mark invalid fields with
aria-invalid="true"
Example:
<label for="email">Email address</label>
<input
id="email"
type="email"
aria-describedby="email-error"
aria-invalid="true"
/>
<p id="email-error" class="error" role="alert">
Please enter a valid email address.
</p>
With this setup:
- The input is marked invalid (aria-invalid=“true”)
- The screen reader announces the error (aria-describedby links the field to the message)
- The message is announced immediately (role=“alert”)
Watch Out For
- Errors that are only visual (e.g., red border or icon with no text)
- Messages that are not connected to their inputs
- Using vague messages like “This field is required” without context
- Not marking inputs as invalid (aria-invalid)
Bad Example:
<input type="text" placeholder="Email" />
<!-- visually red border, but no label or error text -->
Fix (as displayed above):
<label for="email">Email</label>
<input
id="email"
type="email"
aria-describedby="email-error"
aria-invalid="true"
/>
<p id="email-error" role="alert">Email is required.</p>
Pro Tip
Use aria-errormessage instead of (or alongside) aria-describedby for clearer semantics when the message only applies during an error state:
<input id="email" aria-invalid="true" aria-errormessage="email-error" />
<span id="email-error" role="alert"> Please enter a valid email. </span>
Bonus: Also focus the first invalid field on submit failure so users can fix things quickly.
Do this today: Try submitting an empty or invalid form on your site. Are errors clearly visible? Are they read aloud by screen readers? Do they tell the user how to fix the issue?
If not, add proper labels, associate messages programmatically, and use aria-invalid.