kmc234
kmc234

Reputation: 121

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

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.

Upvotes: 12

Views: 16577

Answers (4)

Donovan Pardo
Donovan Pardo

Reputation: 141

In my case I used for iOS VoiceOver:

<span role="text" aria-label="audible text">visible text</span>

it is important to add the attribute role="text" so that VoiceOver reads the attribute aria-label=""

Upvotes: 4

Yop
Yop

Reputation: 115

You could use the abbr html element.

For example :

<abbr title="HyperText Markup Language">HTML</abbr>

Upvotes: 1

unobf
unobf

Reputation: 7244

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

Upvotes: 10

Daniel G&#246;ransson
Daniel G&#246;ransson

Reputation: 1165

In this case you could use a pattern that hides the visual text from screen-readers and hide the screen-reader text from showing visually. Like this:

<span aria-hidden="true">1:02a Dec</span>
<span class="visually-hidden">1:02 AM December</span>

and use CSS to hide .visually-hidden for example like this:

.visually-hidden {
  position: absolute;
  left: -999em;
}

Don't use display:none since it removes the element from being sent to the accessibility API.

As a side note: use role="heading" carefully if ever, and if so use an appropriate aria-leve="#" number/level.

Upvotes: 2

Related Questions