I have this content (simplified):
<div>
$<span class="enlarged-text">245</span>.50
</div>
And when I use CAPSLOCK + Right
(read next element) with Voiceover on Safari (MacOS Monterey 12.7.1) it reads it out as "two hundred and forty five dollars and fifty cents", as desired.
However, using the auto-readout feature of voiceover – initiated using CAPSLOCK + A
– voiceover quite bizarrely reads out "two dollars, forty five point five zero". Is there a way to fix this?
I’ve tried the undocumented role="text"
on the surrounding div and it helps somewhat, but instead reads out as "two hundred and forty five dollars, fifty" using the auto-readout. And using CAPSLOCK + Right
it reads as "two hundred and forty five dollars point five zero".
<div role="text">
$<span class="enlarged-text">245</span>.50
</div>
I also tried surrounding each piece in a separate span
, but it made no difference:
<div role="text">
<span>$</span><span class="enlarged-text">245</span><span>.50</span>
</div>
2
Answers
Since you are experiencing inconsistent behavior with Voiceover’s automatic readout feature, try and Use the
aria-label
attribute to explicitly specify the text that should be read out by Voiceover (ARIA: Accessible Rich Internet Applications).You can also use the
aria-hidden
attribute to hide the elements that are causing incorrect readouts from the screen reader, and add a visually hiddenspan
that contains the correct format for the screen reader..visually-hidden
is a class that hides the content visually but keeps it accessible to screen readers.It would be defined as:
(From "CSS in Action / Invisible Content Just for Screen Reader Users")
You might also try using the
content
CSS property with the::before
or::after
pseudo-elements to inject the currency symbol, which may not interfere with Voiceover’s readout logic.As noted by QuentinC in the comments:
Actually,
aria-label
can sometimes be used on non-interactive elements to provide an accessible name, but its support can indeed be inconsistent across different screen readers and scenarios.The goal remains to make sure the screen reader correctly interprets the dollar amount as a whole number followed by the cents, without being misled by the HTML structure.
You could try and combine the dollar sign and the number in a single
span
without visual space, and then use CSS to visually enlarge only the dollar amount part.Alternatively, if modifying the visual appearance is not an option, you could use JavaScript to dynamically set the
aria-label
attribute based on the content of the spans when the page loads or when the content changes.The JavaScript approach manipulates the
aria-label
dynamically, making sure the label is always set to the correct dollar amount that needs to be read out.If none of the above solutions work due to the specific quirks of Voiceover, check, as QuentinC suggests, if any existing CSS rules are interfering with the screen reader’s ability to correctly interpret the content.
To mitigate the risk of content getting out of sync, you could use JavaScript to dynamically update the visually hidden text based on the visible content.
That way, any changes to the visible price would automatically be reflected in the screen reader text.
Use a visually hidden span in addition to the visible content.
Make sure it is accessible to screen readers but not visible.
Dynamically set the content of the visually hidden span.
That approach would make sure the screen reader text is always in sync with the visible text.
It requires a bit of extra effort to set up, but it effectively addresses the concern of maintaining consistency between what is read by screen readers and what is seen by sighted users.
Using JavaScript you could make it a bit dynamically but not perfect at all