Try this on your own contact form. Leave the email field blank, press the send button, and then close your eyes. What do you know? On a lot of WordPress sites the answer is nothing: a red outline appeared around one box, or a line of small red text showed up at the top, and the page itself said nothing at all.
Accessible error messages fix that. They tell people that something went wrong, which field it was, what the problem is and how to put it right, in a way that reaches someone using a screen reader, someone zoomed in to 400 percent and someone who simply does not see red. This post covers what WCAG asks for, the two main patterns (inline messages and an error summary), and how to check what your forms do today.
What WCAG asks for
Three success criteria do most of the work here.
- 3.3.1 Error Identification (Level A). If an input error is detected automatically, the field in error is identified and the error is described to the person in text. A red border alone does not do this.
- 3.3.3 Error Suggestion (Level AA). If you know how to fix it, say so. “Enter a date in the format MM/DD/YYYY” is a suggestion; “Invalid input” is not. The exception is where a suggestion would weaken security, such as hinting at the right password.
- 4.1.3 Status Messages (Level AA). Messages that appear without moving focus, such as “3 errors found” or “Your message has been sent”, must be announced by assistive technology without the person having to go looking.
Two more apply quietly. 1.4.1 Use of Color means the error cannot be shown by color alone, and 1.4.3 Contrast (Minimum) means the red text itself needs a 4.5:1 contrast ratio against its background, which many pale reds miss.
Writing accessible error messages: the words first
Before any code, get the words right. A good error message:
- Names the field. “Email address is required”, not “This field is required”. When several errors are read out in a row, “This field” tells you nothing.
- Says what is wrong. “Phone number has too few digits.”
- Says how to fix it. “Enter a 10-digit US phone number, for example 555-201-0123.”
- Is polite and plain. No error codes, no “Oops!”, no blame.
| Weak | Better |
|---|---|
| Invalid input | Enter your ZIP code as 5 digits, for example 30301 |
| Error | Choose a preferred appointment day |
| Please fix the errors below | 2 fields need attention: Email address, Date of birth |
| Passwords mismatch | The two passwords do not match. Type the same password in both fields |
Where possible, prevent the error rather than reporting it. Accept phone numbers with or without dashes. Accept “march 3” and “3/3” if you can parse them. Every format you accept is an error that never has to be explained.
Inline errors: next to the field
An inline message sits directly beside or below the field it belongs to. It is what most people look for, and it helps anyone using magnification, because the message is right where they are already looking.
The message must also be connected to the field in the code, so a screen reader reads it when the field gets focus. Here is a simple pattern:
<label for="your-email">Your email</label>
<input id="your-email" type="email" aria-invalid="true"
aria-describedby="your-email-error">
<p id="your-email-error">Error: Enter your email,
for example name@example.com</p>
Three details carry the weight. aria-invalid="true" tells assistive technology the field has a problem, and should be removed once it is fixed. aria-describedby links the message to the field, so focus on the field reads something like “Your email, invalid entry, Error: Enter your email”. And the word “Error:” at the start of the text means the message still makes sense in high-contrast modes or to someone who cannot see color.
Add an icon if you like, but next to text, never instead of it.
Error summaries: at the top of the form
On long forms, such as an application, an intake form or a multi-step checkout, it helps to show a summary as well. After someone submits, a box appears at the top saying how many problems there are and listing each one as a link to its field.
<div id="error-summary" tabindex="-1">
<h2>There are 2 problems with your form</h2>
<ul>
<li><a href="#your-email">Enter your email</a></li>
<li><a href="#dob">Enter your date of birth</a></li>
</ul>
</div>
When the form fails to submit, move keyboard focus to that summary (that is what the tabindex="-1" allows). A screen reader then reads the heading straight away, and the links take people to each field. Keep the inline messages too; the summary helps people find the problems, the inline message helps them fix each one.
Which pattern should you use?
For a short contact form with three or four fields, inline messages plus moving focus to the first field in error is usually enough. For anything longer, use both. What you should not do is show only a summary at the top with no link to the fields, or only red outlines with no text.
Announcing errors and moving focus
Whatever the visual design, someone who cannot see the page needs to learn that the submit failed. There are two main ways:
- Move focus to the error summary or to the first field with an error. This is the most reliable approach after someone presses submit.
- Use a live region (for example an element with
role="alert"oraria-live) that announces the message without moving focus. This suits checks that happen as people type or leave a field.
Be careful with checks that fire on every keystroke. If a message announces “Invalid email” after each letter someone types, the screen reader keeps interrupting them. Validate when someone leaves the field or submits, not while they are still typing.
Also avoid messages that vanish on a timer. A toast that says “Please complete all fields” for three seconds and fades away can be missed by anyone who reads slowly or is zoomed in elsewhere on the page.
Success messages count too
Criterion 4.1.3 is not only about errors. When a form sends successfully and the page does not reload, the “Thank you, we received your message” text must be announced. Many AJAX forms show a green box where the form used to be and leave focus on a button that no longer exists. The person using a screen reader is left in silence, unsure whether to press send again.
Either move focus to the confirmation message, or put it in a live region, or send people to a separate thank-you page with a clear heading. Our post on setting up a thank-you page after a form submission covers the third option.
Checking the forms you already have
Six quick tests show whether a form already has accessible form error messages or only red outlines:
- Submit each form empty. Is there a text message for every required field?
- Enter a wrong format (letters in a phone field). Does the message say how to fix it?
- Look at the page in grayscale (most operating systems have a color filter setting). Can you still tell which fields are in error?
- With a screen reader on, submit the empty form. Do you hear that it failed, and where focus went?
- Tab to each field in error. Is the message read along with the label?
- Fix the errors and submit. Is success announced?
Form plugins differ a lot in how close they get to accessible error messages out of the box. Some add aria-describedby and move focus well; others only add a CSS class that colors the border. Testing each form, as our guide on testing WordPress forms before your customers do recommends for delivery problems, is the only way to know. If you are tempted to patch a plugin’s messages with extra ARIA, read about when ARIA labels help and when they harm first; a wrong attribute can make things worse.
How your fields are labeled and laid out in the first place makes errors easier to handle; that side is covered in our post on accessible form design. Checkout forms, where errors cost sales, are part of the wider guide to accessibility across an online store.
Frequently asked questions
Is a red border around a field enough to show an error?
No. WCAG 3.3.1 requires the error to be described in text, and 1.4.1 says color cannot be the only way information is shown. A red border is fine as an extra cue, but there must also be a written message near the field that names the problem and is connected to the field in the code.
Should errors appear at the top of the form or next to each field?
Next to each field in every case, and also in a summary at the top for longer forms. The inline message helps people fix the field they are on. The summary, with links to each field and focus moved to it after submit, helps people find every problem without hunting through the whole page.
Why does my screen reader not announce form errors?
Usually because the message appears on the page without focus moving and without a live region, so assistive technology has no reason to read it. The fix is to move focus to an error summary or the first field in error, or put the message in an element marked as an alert, and link inline messages to fields.
Should I validate fields while the person is typing?
Generally not. Messages that appear after every keystroke interrupt screen reader users and distract everyone else. Check a field when the person leaves it or when they submit the form. A positive hint while typing, such as a password strength meter, is fine if it does not announce constantly.
Error handling is one of the first things we test on any form, because a form that fails silently is a form people abandon. If you want help reviewing and fixing yours, our accessible form fixes page explains what we look at, store checkouts are covered on the WooCommerce accessibility page, and the rest of our website accessibility services start from the same testing.
Next in this series: CAPTCHA Accessibility and Alternatives That Work