8

As I understand it's not recommended to add duplicate roles to an element:

<nav role="navigation"></nav>

This is redundant because nav tells the screen reader what the semantics of content is already. So far so good.


Now I want to invalid a form field. I understand that classical I should transform this:

<input type="text" name="username">

… into

<input type="text" name="username" aria-invalid="true">

… after form submission.


However, we are using JavaScript and the HTML5 constraint validation API to check the input before sending it to an API. And yes, the input is again tested on the server side.


So, let's say I invalidate the field:

input.setCustomValidity('This value is invalid');

Do I still need to add aria-invalid="true" to the input?

I'd say no, because it is redundant to what the engine already knows. But I can't find any source describing this scenario explicitly.

lampshade
  • 2,470
  • 3
  • 36
  • 74

1 Answers1

11

aria-invalid is a hint to screen readers that the field is in error. As a screen reader user tabs through the <input> fields, they will be notified if the field is invalid.

Using aria-invalid should be used in conjunction with associating an error message with the field too (via aria-describedby). If you display an error below the field without associating that error with the field, the screen reader user won't know about it. If you use aria-invalid by itself, the user would not know why the field is in error.

So you should have something like:

<input type="text" name="username" aria-invalid="true" aria-describedby="errmsg">
<span id="errmsg">The name you entered cannot be found in our system</span>

Update: After further clarification, I see what the OP is asking for now, and the reference to not using duplicate information, such as <nav role="navigation>.

With the validation api, the pseudo classes (such as :invalid) are set, but screen readers, in general (*), do not know or care about CSS and don't know anything about the pseudo classes.

((*) The only exception is :before/:after, which can be used in the accessible name calculation as noted in step 2.F.ii of https://www.w3.org/TR/accname-1.1/#step2).

However, in addition to the pseudo class :invalid being set, obj.validity.valid is also set. So if that attribute is set, do you also need to use aria-invalid? Or another way to ask, do screen readers know about the validity.valid attribute?

I couldn't find any documented references pertaining to screen readers, but from testing, both firefox and chrome surface validity.valid to the screen reader (JAWS and NVDA) so they announce the field is invalid. But Internet Explorer (I'm on Win7 so don't have Edge) and Safari on iOS (I don't have a Mac to test) do not surface the field in error.

So to cover all your bases, I would recommend setting aria-invalid. It's great that you don't want to be redundant, but at least being redundant doesn't hurt anything. It's just extra code or typing you have to do.

slugolicious
  • 15,824
  • 2
  • 29
  • 43
  • Thanks for your feedback. While this is all correct, it doesn't really answer my question: Does the screen reader know, that a field is invalid solely from the Vaildation API? If yes, wouldn't this be sufficient: `` after validation? Or do I still need to add `aria-invalid="true"`? I'm wondering if the error would be announced twice if the field is marked as `invalid` and `aria-invalid` is present. Hopefully, this make my question a bit clearer. – lampshade Oct 04 '18 at 18:12
  • What is the validation api? Unless the api sets the `aria-invalid` attribute, a screen reader will not know the field is invalid. – slugolicious Oct 04 '18 at 22:03
  • See: [HTML5 constraint validation API](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation#Validating_forms_using_JavaScript). This will make it possible to use the pseudo classes `:valid`, `:invalid`, `:in-range` and `:out-of-range` wich can be targeted by CSS: `input:invalid { border: 1px solid red; }`. Now, the browser seems to know, that a field is valid or invalid. The question is, is this enough for the screen reader to know it as well? – lampshade Oct 05 '18 at 08:59
  • I see what you're saying now. I'm updating my answer. – slugolicious Oct 05 '18 at 14:10
  • Thanks a lot for your effort. This is the answer I was looking for - very helpful. – lampshade Oct 10 '18 at 17:39
  • This answer is excellent, however it could use some editing such that it answers the question more clearly. Ideally it should provide a clear answer in the first paragraph (as is it provides a marginally related information on top; which should probably be moved further down). The actual answer is in the second to last paragraph and should probably be moved to the top. – Rúnar Berg Sep 03 '21 at 18:27
  • 1
    I appreciate the opinion but the FAQ for writing a good answer doesn't mention any of your thoughts - https://stackoverflow.com/help/how-to-answer. I would recommend that you provide feedback to stackoverflow to update that FAQ, – slugolicious Sep 05 '21 at 16:22