aria-label and label not both read

Tim picture Tim · Apr 2, 2014 · Viewed 23.6k times · Source

Please consider the following markup.

<label for="i1" class="inforLabel">This is a label</label>
<input id="i1" type="text" class="inforTextbox" aria-label="Title, not label" />

For me this markup is what is generated after my custom tooltip control. The issue I am seeing on JAWS on IE is that it only reads "Title, not label", however with other screen readers for example Voice over both the label and the textbox aria-label is read. I think it should read both.

Is this a setting or a bug? Or is there something else someone can recommend?

Answer

Nick picture Nick · Jul 11, 2014

For elements which have a descriptive label element already in the DOM, it is best to use the aria-labelledby attribute, instead of aria-label.

https://www.w3.org/TR/wai-aria/#aria-labelledby

From the documentation:

The purpose of aria-labelledby is the same as that of aria-label. It provides the user with a recognizable name of the object.

If the label text is visible on screen, authors SHOULD use aria-labelledby and SHOULD NOT use aria-label. Use aria-label only if the interface is such that it is not possible to have a visible label on the screen.

Individual screen reader and browser combinations can give inconsistent results when you don't follow the standard recommendations, as the WAI-ARIA spec can be open to interpretation.

Is is generally not a good idea to associate multiple labels with an accessible element. Labels should be concise. If you want to add extra description, you may also want to use aria-describedby.

https://www.w3.org/TR/wai-aria/#aria-describedby

In both cases, you will need to have an id on your label.

<label id="label1" for="input1" class="inforLabel">This is a label</label>
<input id="input1" type="text" class="inforTextbox" aria-labelledby="label1" />

Optionally, if you need to have multiple elements, you can try to put them in a div, with one element being offscreen.

<div id="accessible-label1">
  <label for="input1" class="inforLabel">This is a label</label>
  <span class="offscreen">Supplementary text</span>
</div>
<input id="input1" type="text" class="inforTextbox" aria-labelledby="accessible-label1" />

With appropriate CSS to position the offscreen class element off the screen, this should combine the text-content of the children of accessible-label1 to use as the aria-label. Again, consider the use of aria-describedby.