For iOS, Safari, VoiceOver, how do I get VoiceOver to read something other than the text content?

kmc234 picture kmc234 · May 7, 2014 · Viewed 10.1k times · Source

I am trying to get VoiceOver to say something other than the specified text content in an HTML span element:

<span tabindex="0" class="myClassName" id="DateLabel" role="heading">1:02a</span>

Consider the case where I might like VoiceOver to say the full time text.

When I add the aria-label attribute, VoiceOver is still reading the text, despite desktop browsers like IE and Chrome correctly reading the aria-label instead.

When I add the aria-labelledby attribute plus a hidden aria label element, I am able to get VoiceOver to read the alternate narration, and NOT the text content. However, I find this only works if the aria-role is a widget role like button or link. This is bad because I don't want to imply to users that this is an interactive element they can activate. VoiceOver annoyingly appends "button" to the end of the narrated sequence. I would prefer to use a structural role like "heading" but then VoiceOver just reverts reading the text content instead of reading my hidden narration.

Please help! I've been bashing my head against this but I simply cannot stand iOS's non-standard implementation of ARIA. I don't understand why they must be different from desktop browsers for something so simple but they are in so many places and I cannot find a good document outlining the exact behavior anywhere.

Answer

unobf picture unobf · Dec 24, 2014

You can use aria-label like this:

<span tabindex="0" class="myClassName" id="DateLabel" role="heading" aria-label="1 0 2 am">1:02a</span>

However, why are you setting tabindex to 0? For a heading this is not a good practice because screen reader users can navigate between headings using the keyboard commands. Also, you will want to set aria-level on your heading to indicate what level it is.

The best markup to use for this is:

<span class="myClassName" id="DateLabel" role="heading"
aria-level="2" aria-label="1 0 2 am">1:02a</span>

Update: This appears to no longer work for at least some versions of VoiceOver, it will read the visible content and ignore the aria-label. See this bug - https://bugs.webkit.org/show_bug.cgi?id=160009