How to fix role="text" around links or buttons?

aria-text page

The issue

A keyboard user tabs to a link or button that a screen reader announces as plain text, or doesn’t announce at all. The control is still in the tab order, but role="text" around it has asked assistive technology to treat everything inside as one run of text. The user reaches something they can activate without being told it is a control.

The cause is role="text" used to stop a screen reader splitting styled text into pieces, such as a price written as <span>$</span><span>29</span>, and then applied to a container that also holds a link or button. role="text" isn’t in the published ARIA specification; some browsers support it for exactly that purpose, which is why it should only wrap text. WCAG 4.1.2 requires every control’s name and role to be available to assistive technology.

Scope

Every visible element with role="text" is checked. It fails if anything inside it is focusable: a link with an href, a <button>, <input>, <select>, <textarea> or <summary>, or any element with a tabindex, unless it is disabled or has tabindex="-1".

How to check you have it

  • In probeo: the page reports aria-text, “"role=text" should have no focusable descendants”, with serious impact.
  • By hand: search the page source for role="text" and look inside each match for links, buttons, form fields and tabindex.
  • With a tool: axe DevTools reports the same rule id.

The fix

Keep role="text" on text only, and move any link or button outside it.

Narrow the element with the role so it wraps just the split-up text, and let the control sit beside it.

<!-- Before -->
<p role="text"><span>$</span><span>29</span> per month <a href="/pricing/">See plans</a></p>

<!-- After -->
<p><span role="text"><span>$</span><span>29</span> per month</span> <a href="/pricing/">See plans</a></p>

Done when: no element with role="text" contains a focusable element, and the check above comes back clean.

Do not

  • Do not put role="text" on a container of controls, such as a card or a list item with a link.
  • Do not add tabindex to an element inside role="text".

FAQ

Should role="text" be used at all?

Only to keep a short piece of styled text from being read in fragments, and only where that matters. Many pages split text across elements without any problem for screen readers, so check the reading first.

It can still be clicked and focused. What changes is how assistive technology may announce it, and that varies between browsers. A control whose announcement depends on the browser is the problem this rule exists to catch.

What if a component library adds it?

Check whether the component exposes a way to render its contents without the role. If it doesn’t, keep links and buttons out of the component and place them next to it.

Which product detects this

Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.