Using the “text” role

Every now and then, in internal discussions, the question pops up around the usage of a mysterious and not-very-often-seen role attribute of text. What is this role? And why do we occasionally see it being used?

The use of role="text" is not valid ARIA (and usually the trigger for discussions about its presence on a page having run markup through the validator). This role was considered for ARIA 1.1 but was not ultimately included. However it does have some proprietary support in Webkit browsers, and is sometimes used to address a reading quirk in VoiceOver for iOS.

Intended use

When role="text" was first proposed for inclusion in ARIA it was suggested as a way of conveying a non-text element’s textual content without exposing its role. For example, for an image that would typically be read as assumed text, the fact that it’s presented as an image might be considered unimportant to screen reader users. So using this role would announce the alternate text without mentioning that it’s an image.

<p>I <img src="heart.png" alt="love" role="text"> New York.</p>

But there is a debatable assumption in this — how can we be sure that a screen reader user doesn’t want to know that the content is an image? Using role="text" in this context removes semantics that a reader might want, and this could also be considered a failure of Success Criterion 4.1.2 Name, Role, Value since the image has lost its role.

Practical use

The way this role has been used in practice is to compensate for a quirk in the way VoiceOver for iOS handles sentences which have inline markup such as <em> or <span>.

<p>This is a simple sentence.</p>
<p>This is a sentence <em>with emphasis</em> inside it.</p>
<p>This is a sentence <span>where some of the text</span> has been <span>split into span elements</span>.</p>

JAWS, NVDA, TalkBack, and VoiceOver for MacOS, treat each of those paragraphs as a single object, reading each as a single uninterrupted sentence.

However VoiceOver for iOS breaks the sentence into separate fragments, requiring multiple side-swipe gestures when navigating through the paragraph, behavior which might be considered a usability problem.

Using role="text" changes that behavior, causing each of the paragraphs to be treated as single objects.

<p role="text">This is a simple sentence.</p>
<p role="text">This is a sentence <em>with emphasis</em> inside it.</p>
<p role="text">This is a sentence <span>where some of the text</span> has been <span>split into span elements</span>.</p>

Problematic use

The risk with using role="text" in this way is that it overrides the implicit role of any element that it’s used for, and will override the roles of any inner elements. Using it on a heading, for example, will remove the heading semantics and treat the element as plain text, while using it on a paragraph which contains a link will remove the semantics of the link.

<h3 role="text">This should be a heading</h3>
<p role="text">This is a sentence with <a href="#">some link text</a> inside it.</p>

In both of those examples, VoiceOver for iOS treats the whole element as plain text — it does not announce the heading as a heading, and does not announce the link as a link, nor does it pause before the announcement of the link text, which is otherwise expected behavior for a sentence containing a link. In fact in the latter case, it’s no longer possible to navigate to the link at all.

Recommendation

Using role="text" should not be encouraged for any purpose.

To a developer or user who is used to the way JAWS or NVDA announces content, the behavior of VO might seem fragmented and annoying, but to someone who regularly uses VO, this pattern of speech output is usual, and may be the expected or even preferred pattern. It’s not necessarily accurate to call this a usability problem at all, and it’s not safe to assume that the typical behavior of an assistive technology is something that needs to be “fixed”, simply because it’s inconsistent with the behavior of similar technologies. In any case, this quirk only exists at all when navigating with the default side-swipe gesture pattern, it doesn’t occur when navigating using rotor lines navigation, or when VO reads continuously (but the problems caused by overriding semantics do still occur in all circumstances).

Having said that, the use of role="text" should not be considered a WCAG failure, unless it’s been used on an element which should have different explicit semantics, or it inappropriately overrides the semantics of an element or its children.

Resources

Categories: Development

About James Edwards

I’m a web accessibility consultant with around 20 years experience. I develop, research and write about all aspects of accessible front-end development, with a particular specialism in accessible JavaScript. I can also turn my hand to PHP and MySQL when it’s needed. I started my career as an HTML coder, then as a JavaScript developer, but the more I learned, the more I realised just how important it is to consider accessibility. It’s the basic foundation of web development and a fundamental design principle of the web itself. If information is not accessible, then what’s the point of any of it? Coding is mechanics, but accessibility is people, and it’s people that actually matter.

Comments

Apple partially fixed this problem several releases ago. I don’t have the exact number but my old iphone 6 running 12.5.5 reads the <em> and nested examples just fine. I don’t need to swipe several times to hear the full sentence. And my new iphone running 14.8 works too. Apple still splits the reading if there are nested blocking elements but nested inline elements work ok. What version did you test with?

James Edwards says:

I tested this on an iPhone 7 running iOS 14.8, and I got the behavior described in the article. The sentence splitting only happened with default navigation, not with the other methods available through the rotor.

This is the test page I used: https://brothercake.com/reference/role-text.html

Ahh, I see the difference. Apple fixed *links* with inline elements but *paragraphs* still split. Wonder why they only fixed one element. The splitting used to be a problem with links but I guess enough people complained about it that that element was fixed.

Add Your Comment