How to make screen reader reads aria-label inside <span>?

2.8k Views Asked by At

I'd like the screenreader to read the text "Stories, menu item" when the mouse hovers over the "Stories" button in the menu bar. I have tried to add aria-label as well as aria-describedby inside the span but the screenreader is still reading the "Stories" text, instead of "stories, menu item" text.

Original code:

<li role="menuitem">
     <span class="">Stories</span>
</li>

Things that I tried but doesn't work:

(1) Adding aria-label

 <li role="menuitem">
         <span class="" aria-label="stories, menu item">Stories</span>
 </li>

(2) Adding aria-describedby

 <li role="menuitem">
         <span class="" aria-describedby="stories, menu item">Stories</span>
 </li>
2

There are 2 best solutions below

1
Aryan On

You can include some additional text for screen readers only:

<li role="menuitem">
    Stories<span class="screen-reader-only">, menu item</span>
</li>

CSS taken from Bootstrap 3:

.screen-reader-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

Adapted from this answer.

0
slugolicious On

There are a few weirdnesses going on.

First off, in your OP, you asked about reading text when the "mouse hovers over" the element. Most screen reader users will not be using a mouse and will not hover over elements. The NVDA screen reader has a mouse hover option so that moving the mouse over elements will read it, but that feature is mainly for sighted testers. I have never found a use for the mouse hover NVDA feature.

So I'm guessing your question is more about when the user navigates to the item, you want it to read additional text. More than what is visually displayed.

The code you posted doesn't actually have a keyboard focusable element although you mention a "button" in your description. I'll gloss over that for now and assume you have a focusable element, preferably a native semantic HTML element.

Another weirdness is that you want to announce "menu item" (presumably because you're not hearing that announced) but that text should be announced based on the role of your element, which is "menuitem". You shouldn't have to force an announcement of the role of the element. You get that for free when using a semantic html element or the proper use of role. In this case, "menu item" should be announced if the element that receives focus has role="menuitem". In your case, your code example might be too simplified but as it stands, the <li> has the menuitem role but the <li> is not the element receiving focus. The element inside the <li> (a button?) is receiving focus.

Lastly, the crux of the problem is that an aria-label on a <span> is generally not supported unless that span has a role. See the third last bullet point on https://www.w3.org/TR/using-aria/#label-support. But again, you shouldn't have to force "menu item" to be announced.

Side note: Your third example that uses aria-describedby, the value of that attribute should be a space separated list of IDs. It should not be a literal string.