Reputation: 99
I am building a React site and have to support accessibility across browsers.
On my site I have inputs and I perform the validations only on blur, if the input is not valid - an error message is inserted after the input.
My problem is that the screen reader skips this new error element and jumps to the next one - it seems that the reader calculates the next element when it's focused on the previous one (in my case the input). and therefore when I "tab" and blur out of the input it goes to the next tabbable element - and skips the new error.
The new error element that's getting skipped has all required attributes, (it is getting focused if I do shift + tab from the next element that was reached after the input). I have also tried adding aria-live="assertive" to the new error message element but it doesn't help.
Any solution for this?
Upvotes: 0
Views: 1533
Reputation: 17535
The aria-invalid
and aria-describedby
recommendations by @jongibbons is good but the actual announcement of the error message when it's added should be handled by aria-live
. You mentioned you tried aria-live
but that it didn't work. It might depend how you were trying to use it.
If you try to add that attribute dynamically when the error message is generated, then it won't work. aria-live
must exist on the page before you add text to it. For example, the following won't work:
Before the error:
<input>
After the error
<input>
<div aria-live="polite">this is the error message</div>
If the <div>
is added dynamically, it won't be announced even though it has aria-live
.
Instead, your code should look like this:
Before the error:
<input>
<div aria-live="polite"> <!-- empty area for error message --> </div>
After the error
<input>
<div aria-live="polite">this is the error message</div>
In this case, "this is the error message" will be announced by screen readers when the new text is injected into the page.
And as @jongibbons said, associate the error message with the input field via aria-describedby
.
<input aria-describedby="foo">
<div id="foo" aria-live="polite"> <!-- empty area for error message --> </div>
Upvotes: 2
Reputation: 1086
For the behaviour you describe to be accessible, you want to look at using the aria-invalid
and aria-describedby
attributes.
When a field has an error, toggling aria-invalid
on the <input>
from false
to true
will cause screen readers to announce the change in state.
Adding an aria-describedby
relationship between your <input>
that's in error and the HTML element containing your error message should then also cause the screen reader to announce the error message.
<label for="email">Email address</label>
<input type="text" name="email" id="email" class="error"
aria-invalid="true" aria-describedby="email-error">
<p class="error-message" id="email-error">
Error: This doesn't look like a valid email address
</p>
Here's an example on MDN with code that might match what you need: Using the aria-invalid attribute
Upvotes: 1