Search code examples
htmlaccessibilityvoiceover

Screen reader stops when it reaches a span element


I'm doing some screen reader usability testing and I was wondering if someone could explain to me why a screen reader stops when it reaches a <span /> element.

Example:

<h1><span class="style1">Today</span> is a wonderful <span class="style2">day</span></h1>

The screen reader will read "Today" and then stop rather than reading the entire <h1 /> text.

Note: I'm using the voice over available on an iPad in the Settings > General > Accessibility menu.


Solution

  • As noted by @vanita and by my comment in Making an h2 tag with a strong tag inside accessible from three years ago, that's just how VoiceOver works. There could be some semantic significance among the elements so VoiceOver is going to stop on each one.

    There is a workaround, though, but it's undocumented and only affects VoiceOver (not JAWS or NVDA). Use role="text". However, since it's undocumented, you run the risk of it not working at some point in the future.

    Be careful how you use it because you don't want to lose the semantic meaning of the heading. Let's start with the original problem, something like this:

    <h1>hello <strong>there</strong> world</h1>
    <h1>hello <span class="myclass">there</span> world</h1>
    

    It doesn't matter if the embedded element is semantic (<strong>) or not (<span>).

    role="text" should not be put on the <h1> directly because that would remove the semantic meaning of the heading:

    <h1 role="text">hello <strong>there</strong> world </h1> <!-- DO NOT DO THIS -->
    

    Instead, embed all the inner text in a <span> and specify role="text" on the inner span.

    <h1><span role="text">hello <strong>there</strong> world</span></h1>
    

    This will cause "hello there world" to be read as one element and will still say the entire thing is a heading.