Search code examples
htmlaccessibilityscreen-readers

How do screen readers handle text separated by tags (not spaces)?


For stylistic reasons I have HTML markup as follows:

h1 {
  font-family: 'Heebo', sans-serif;
  font-weight: 900;
}

h1 span {
  font-weight: 100;
  color: yellow;
}
<link href="https://fonts.googleapis.com/css?family=Heebo:100,900" rel="stylesheet">
<h1>Big<span>yellow</span>bananas</h1>

This allows me to style yellow differently and because it is styled differently, I can remove the spaces between the words so that the text looks nice yet is still readable by humans. However, this got me thinking. How is such text handled by search engines and screen readers? Assuming that they treat the heading as a single string Bigyellowbananas rather than Big yellow bananas, what is the correct way to maintain the visuals but improve the accessibility?

My guess would be zero-width spaces but I am not sure about this.


Solution

  • Actually, it depends on the screen reader whether or not it is read as a single word. Jaws is most certainly going to read your text as a single word, while VoiceOver will read three words, perhaps even making an exagerated pause between them.

    Ideally, as a safety, you should put an actual spaces between the words, so that you make sure everything is well read everywhere. It doesn't matter if the space is just before </span> or just after <span>. IN fact, if you remove all HTML tags, it's obvious to see where you should put spaces.

    Unfortunately I'm not a CSS expert but I'm pretty sure there is a solution with a code having correct spaces. Couldn't you change your code for something like this for example?

    <h1>My<span class="space"> </span><span class="big">yellow</span><span class="space"> </span></h1>

    Where .space could be in fact .sr-only, reduce the width to 1px, send off-screen or any other usual CSS trick of the same kind.

    ARia-label isn't a full proof solution here in my sense. It is normally used in element interactions, but in a context where you just have text with no interaction, it isn't guaranteed to always work. Some screen readers need a role, otherwise they ignore aria-label if there isn't also a role. However, here, <h1 role="heading"> is a bad practice, you are explicitely giving the role of something implicit (this can make other troubles). role="text" or role="presentation" are much worse, they both makes the heading be totally skipped when navigating from heading to heading or when listing all the headings of the page.

    To come back to the main question, note that VoiceOver hasn't always the correct expected behavior. Consider this:

    <p>This is <span style="color: blue;">blue</span>.</p>

    No problem with Jaws or NVDA, but I have already seen VoiceOver explicitely saying "period" on such codes, exageratly detaching the word "blue" from the sentance. In that case however, I don't think there is an easy way to change the HTML in order to have a correct reading everywhere.