Adam Mor
Adam Mor

Reputation: 99

Screen reader skips new inserted elements

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

Answers (2)

slugolicious
slugolicious

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

Jon Gibbins
Jon Gibbins

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

Related Questions