Broken Copy

Most of what’s written on this site illustrates the differences between how screen readers handle “situations”. There are differences between the OS, too. In this article we’re going mobile.

But first let's have a look at a headline or a link. Normally we have some copy wrapped inside a start tag and an end tag. Screen readers have no problems detecting headlines or links. They read out the copy and the kind of element the content is wrapped in. It's not a problem to do some "fancy stuff" with the copy, like emphasise a word or make it big. Sometimes a designer demands a break within the text because ... well, it’s what they want. In every browser and screen reader this is no drama - accept in VoiceOver on iOS (and macOS).

Assuming there’s a headline and one word is to be in italics. The developer will use e.g. a <h1> and put an <em> around a word. Maybe the developer won't use an <em> but instead he’ll use a <span> with some CSS. Either way, VoiceOver on iOS will read out every "chunk" of the headline individually. Like this:

<h1>Scientists find out: Ducks <em>are</em> evil</h1>

will become this:

Scientists find out: Ducks, heading level one. Are, heading level one. Evil, heading level one

The same goes for links:

<a href="#">Buy <em>more</em> carrots</a>

will become:

Buy, link. More, link. Carrots, link

By the way, this problem isn’t just limited to iOS. VoiceOver on macOS has some issues with these "breaks" as well.

How to fix it

If your designer is insisting on these “visual gimmicks” and you want to give iOS users a nice and smooth user experience, you'll have to add a little bit of aria magic to your markup. You can fix the problem by using role="text". That way VoiceOver will read the whole copy as it should be. But be aware that you can't add the role="text" to the mother element. By adding role="text" to the headline, the headline will lose its semantic value.

Don't do this:

<h1 role="text">Scientists find out: Ducks <em>are</em> evil</h1>

VoiceOver will read:

Scientists find out: Ducks are evil

VoiceOver will not recognise the headline as a headline. To avoid this, you'll have to add the aria attribute to an inner element, like this:

<h1><span role="text">Scientists find out: Ducks <em>are</em> evil</span></h1>

Video example

This video shows how extra markup within a headline or a link will break the copy and how you can fix it with an aria attribute. It's broken on iOS and on macOS, too.

What about aria-label?

Well, we could do this:

<a href="#" aria-label="Buy more carrots">Buy <em>more</em> carrots</a>

Besides that this seems a little bit over the top - having a text within a link and the content of the aria-label is exactly identical - the problem is still the same. The copy gets "broken" on iOS.


To give every assistive technology the same content, you could add extra markup with some aria attribute - or you could convince your designer to avoid these extra decorations.

(This topic is inspired by this Axess Lab article)