Testing error messages with JAWS and NVDA
with aria-describedby
, aria-errormessage
and aria-live
(May 2020)
TLDR; Until aria-errormessage
is supported do this:
- add
aria-describedby
to the field to associate it with the corresponding error - add
aria-invalid="true"
to the field when error is triggered - Don't add
aria-live
to the error container. REASON: It cau Zses double speak in NVDA and JAWS, and prevents VoiceOver from recognizing thearia-describedby
.
Once aria-errormessage
is supported by NVDA and VoiceOver (Don't hold your breath, it's been about 6 years!)
- add
aria-errormessage
to the field to associate it with the corresponding error - add
aria-invalid="true"
to the field when error is triggered - Add
aria-live
to the error container
Full Article and testing fields
The aria-errormessage
attribute is now supported by JAWS. I hope NVDA and VoiceOver will follow. Perhaps that will change how error messages are implemented. Until then, if validation is run on the client side when user leaves the field, then the error message shpuld be injected into the page, and the following happens:
-
aria-describedby
is added to the field to associate it with the corresponding error aria-invalid="true"
is added to the fieldaria-live
is placed on the error message so it is read to the screen reader when it appears. (An example of a live region on the error message is in the aria spec).
Today, I was testing this without the aria-live
and I was amazed to find both JAWS and NVDA announcing the error message as soon as the user leaves the field and the error message appears, even though the screennreader was not on the error message. In otherwords, when aria-describedby
is associated with the message, it acted as if aria-live
was on the error message even though it wasn't.
Below are examples error messages that are thrown when the user leaves a field. The first example has aria-live
on the error container, the second doesn't. Then the tests are run again with aria-errormessage
instead of aria-describedby
.
Example 1: Use aria-describedby
to test the error messge with aria-live
Put focus in the field and tab out (its onblur)
Example 2: Use aria-describedby
to test the error messge without aria-live
Put focus in the field and tab out
Example 3: Use aria-errormessage
to test the error messge with aria-live
Put focus in the field and tab out
Example 4: Use aria-errormessage
to test the error messge without aria-live
Put focus in the field and tab out
Example 5: Check to see if the error message remains associated with a field when it has a role="alert"
Put focus in the field and tab out
Results
- When
aria-live
is on the error, NVDA and JAWS read the error message twice (double speak) as the user leaves the field. (Once for aria-describedby and once for the aria-live). - NVDA and JAWS work perfectly well with only
aria-describedby
without thearia-live
. It reads the message as if it hadaria-live
. (COOOL!) - JAWS supports
aria-errormessage
but this attritube would need anaria-live
on the error to be read as the user leaves field as per the example in the aria spec. - Neither NVDA or VoiceOver support
aria-errormessage
at all. (May 2020) - VoiceOver will only read the error when leaving the field if
aria-live
is on the error message. - On VoiceOver
aria-describedby
relationship doesn't work whenaria-live
is on the error message.
Code Used Example 1
<label>First Name <input type="text" onblur="myfun()" aria-describedby="demo"></label>
<div aria-live="polite"><p id="demo" style="color: red"></p></div>
<script>
function myfun() {
document.getElementById("demo").innerHTML = "the one your mama gave you";
};
</script>
Code Used Example 2
Same as #1 above without the aria-live
on the error
Code for Example 3
Same as #1 with aria-errormessage
instead of aria-describedby
Code for Example 4
Same as #1 with aria-errormessage
instead of aria-describedby
without aria-live
on the error
Feel free to comment on Twitter @davidmacd
Author information:
David MacDonald is a veteran WCAG member, co-editor of Using WAI ARIA in HTML5 and HTML5 Accessibility Task Force Member. Opinions are my own.
CONTACT US
For a quote or just to chat about your organization's needs