For iOS, Safari, VoiceOver, how do I get VoiceOver to read something other than the text content?
Solution 1
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
Solution 2
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 attributearia-label=""
Solution 3
You could use the abbr html element.
For example :
<abbr title="HyperText Markup Language">HTML</abbr>
Solution 4
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.
Admin
Updated on June 05, 2022Comments
-
Admin almost 2 years
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.
-
slugolicious almost 10 yearsI think Daniel meant to say role=heading instead of aria-heading. Headings are very powerful to assistive technology users because screen readers such as VoiceOver or JAWS allow the user to navigate by headings so it's very fast to move around the screen. You don't necessarily have to use aria-level when using role=heading. If you want to mimic an <h2> tag, then yes, you need aria-level=2. However, if you are displaying a scrollable list of choices where the choices are grouped together (such as the <optgroup> does), then you don't want the aria-level set. You just want role=heading.
-
Daniel Göransson almost 10 years@slugolicious Thanks, that's exactly what I meant :) and good point about omitting
aria-level
on for example<optgroup>
-
launchoverit almost 8 yearsThis fails for me. Using this markup - <span aria-label="the audible text">the visible text</span> VoiceOver reads "the visible text"
-
unobf almost 8 years@launchoverit that is because you did not use all of the markup I specified. The role="heading" is important because despite aria-label being allowed by the spec on any role, it only works on some roles at the moment. Also, if you downvoted this because you did not use all the markup specified, then that is not cool.
-
launchoverit almost 8 yearsThanks for the clarification about role, I had tried your full markup as well but without success, so I thought posting a more basic markup would simplify my point (obviously wrong about that, sorry). Here’s a codepen with your markup, it still reads “the visible text” for me. codepen.io/anon/pen/dXdEXx.
-
unobf almost 8 yearslooks like this has broken in some version of VoiceOver. I get the rotor showing "the audible text" while VO still speaks "the visible text". This is obviously a regression.
-
launchoverit almost 8 yearsThanks for checking. What's most helpful for this answer at this point? Would an edit to indicate that this no longer works be helpful? I'm happy to add it if you want.
-
unobf almost 8 yearsI have reported a bug to Apple bugs.webkit.org/show_bug.cgi?id=160009 and we should track that. This technique still works in other ATs and is standards compliant. If you want to add information about the lack of support for this technique in VO I think that would be useful.