Just recently I had to fix a pattern in a design system that was causing a lot of errors reported in our automatic accessibility testing. Namely – using aria-hidden="true"
on interactive elements (or their parents). I remembered from my trainings and from research that such a combination is bad for accessibility, as elements still get focused when “tabbing” to them, even when they are deliberately hidden from accessibility tree.
To provide better reasoning to people I train, I decided to experiment what else happens in real world, and decided to write about it here.
Screen-readers behave differently
Before testing it with screen-readers I would imagine that elements with aria-hidden="true"
(on their parent or on themselves) would be totally ignored by screen-readers. I would kind of expect that. Then I would wonder – OK, but what if we use a screen-reader and tab through the page? What happens then?
Well – it depends (almost a trademark). Again – it depends on the screen-reader and browser combination.
I didn’t test with all possible combinations, and I didn’t test with different versions, just latest that I had at hand and this are the results;
- NVDA and Chrome – when we tab to the interactive elements they are announced nameless (so their roles are announced but not their names). Such interactive elements are not available in the elements list and other shortcuts, so basically invisible.
- Narrator and Chrome vs. Edge – tabbing through elements worked just like with normal interactive elements (basically ignoring
aria-hidden="true"
), except that Edge announced wrong role for button, but not for link. Elements were not available in Narrator shortcuts. - VoiceOver and Safari (iOS) – nothing was announced and all elements were unreachable. Even tapping them directly didn’t work. Not a trace in the Rotor menu.
- TalkBack and Chrome (Android) – same as with VoiceOver and Safari – nothing announced, no trace of them anywhere.
Those were just the possibilities at hand and it is actually not relevant what versions I used as you should never use aria-hidden="true"
on parent of -, or directly on interactive elements anyways. But I just wanted to check what consequence does it have for screen-reader users.
It really seems messy, and I think that TalkBack and VoiceOver – totally ignoring interactive elements seems to respect the specification rigidly, while NVDA and Narrator implementation is a bit more permissive.
Mind you – these tests may become irrelevant at any time as things may change, especially for a scenario like this – that should not be used in the real life. But I will for sure remember this experiment the next time I will explain why this is a bad thing, and hopefully so will you.
The code I used for testing:
<section aria-hidden="true">
<h3>parent with aria-hidden with a button and a link</h3>
<button type="button">Test button in a parent</button>
<a href="#">Test link in a parent</a>
</section>
<section>
<h3>Button and link that have aria-hidden attribute</h3>
<button type="button" aria-hidden="true">Independent button with aria-hidden</button>
<a href="#" aria-hidden="true">Independent link with aria-hidden</a>
</section>
Test page if you want to try the scenarios.
How to fix the issue?
Ideally I could just use CSS display:none;
or visibility:hidden;
or HTML attribute hidden
, but that was not the option, as we wanted the content to be “kind of” visible (because of the animation needs).
I just used the – now well supported – inert
HTML attribute. It solves all the problems that aria-hidden="true"
can’t;
- Content, with all children, including interactive elements, is still rendered and visible.
- You can’t tab to interactive elements anymore.
- Content and interactive elements are removed from accessibility tree.
Once again an useful thing to train people with – possibilities we have when we have to think about visibility, keyboard focus and accessibility tree exposure.
Conclusion – beware aria-hidden=true
I don’t use aria-hidden="true"
a lot, even for non-interactive elements, except if I have some redundant icons (icons used in a button or a link where we also have visible text). I didn’t use aria-hidden="true"
for anything else lately, as it can be confusing when we hide something for assistive technologies (like screen-readers), but still show it visually (some screen-reader users can see the screen).
Anyways – don’t use aria-hidden="true"
on interactive elements or their parent elements – now you also know why (if you were a bit skeptical before).
Hello!
FYI: it seems that if Browse mode is turned off, NVDA also reads both name and role of aria-hidden links and buttons, while otherwise just blanks. Checked with NVDA 2024.2
Hi, and thank you for your comment. Good catch, I did not test this in focus mode as I encountered this situation mostly in navigation elements, not so much in forms.
But yes, very interesting indeed.