Categories
HTML Accessibility

The hidden world of aria-hidden

David's head of a suited man sitting, holding a keyboard, with a very old looking PC - a frame from a 1980's tv technology show.
Dr Swallow returns, and it is fair to say, despite a dose of bath salts, he is not pleased with aria-hidden

hides in the light

An interesting feature of aria-hidden is that it hides stuff from screen reader users, but its effects are hidden from everyone else. Unless you going looking for it and understand what it does, you will have no idea how powerful it is and what a detrimental effect it can have if used unwisely, without understanding.

This is further complicated by interoperability issues. The effects of aria-hidden are not consistent across browsers and screen readers.

Take the following quote:

code:

<blockquote aria-hidden="true">
Text available to all except screen readers.
</blockquote>

So far so good

When the descendants of an element aria-hidden=true are non focusable they are chopped out of the accessibility tree in both Chrome and Firefox.

blockquote is not in the accessibility tree
Firefox accessibility tree does not include the blockquote
blockquote is not in the accessibility tree
Chrome accessibility tree does not include the blockquote

What happens when interactive elements are added to the mix?

Browser bifurcation time

Take the following quote:

Code:

<blockquote aria-hidden="true">
<p>
<a href="...">
<span lang="fr">Folie à Deux</span></a> 
(The <span tabindex="-1">X-Files</span>)</p>
<input type="image" src="hides.jpg" 
alt="hides in the light" 
onclick="skinner();">
<p tabindex="0">
<span lang="fr">Folie à Deux</span>, 
a form of insanity shared by two people. 
It usually begins with one person who 
conceives of a delusional belief and 
then spreads it to another; thus, 
those two share the same delusion.</p>
</blockquote>

Splitsville

While Firefox still chops the blockquote and its descendants out of the accessibility tree:

blockquote is not in the accessibility tree
Firefox accessibility tree does not include the blockquote

Chrome exposes interactive elements and elements with a tabindex, which are exposed with states of focusable, invisible, and it appears that Safari on Mac does the same.

<blockquote aria-hidden="true"> <p>
<a href="..."><span lang="fr">Folie à Deux</span></a>
( <span tabindex="-1">X-Files</span> )</p>
<input type="image" src="hides.jpg" alt="hides in the light" 
onclick="skinner();">
<p tabindex="0"> <span lang="fr">Folie à Deux</span>, 
a form of insanity shared by two people. It usually 
begins with one person who conceives of a delusional 
belief and then spreads it to another; thus, those 
two share the same delusion.</p>
</blockquote>
Chrome does not include the blockquote, but it does include the focusable descendants of the blockquote

Special affects

When interactive elements are descendants of an element with aria-hidden="true" (or have it set on the element itself) in Firefox it’s not included in the accessibility tree, but is still focusable, and not announced by Screen Readers such as NVDA and Narrator in Chrome.  This is why I made up the:

4th Rule of ARIA Use

Do not use role="presentation" or aria-hidden="true" on a focusable element .

Using either of these on a focusable element will result in some users focusing on ‘nothing’.

Applying aria-hidden to a parent/ancestor of a visible interactive element will also result in the interactive element being hidden, so don’t do this either:

bad behaviour

  • Chrome exposes focusable aria-hidden content with focusable, invisible states in the accessibility tree. Firefox does not.
  • The content exposed by Chrome is ignored by NVDA, or Narrator (am guessing it’s because they have the invisible state)
  • JAWS  conveys role, state and property information as per usual.
  • On Mac, VoiceOver with Chrome and Safari, acts similarly to JAWS.
  • On iOS the aria-hidden content is ignored by VoiceOver in both Chrome and Safari.
  • Anecdotal observations:
    • Accessible names are announced incorrectly at times on aria-hidden interactive content.
    • Non-interactive content semantics is still hidden from users.

What can we do?

To avoid exposing content when it is supposed to be hidden from SR users, do not put aria-hidden=true on focusable elements or include focusable elements as descendants of an element with aria-hidden=true, as the results are almost always sub-optimal.

Check your usage of aria-hidden to ensure that you are only hiding content that you want to hide:

Visual Bookmarklet for identifying aria-hidden content

As mentioned in the intro, an issue for developers is that use/misuse of aria-hidden is not surfaced for non screen reader users. To help developers I have put together a bookmarklet to visually indicate content, along with some test cases. Go play yourself

heading and blockquote with text 'Text available to all except screen readers.'
The text in the blockquote is visible for sighted users, but not for screen reader users
aria-hidden content is blacked out with an emoji face sticking its tongue out
With the bookmarklet enabled aria-hidden content is hidden from all users

See the Pen
aria-hidden
by steve faulkner (@stevef)
on CodePen.

PS: Don’t get me started on aria-hidden=false

Further listening

Lyrics:

[Verse 1]

This is it, dope from the fly kid

The Ice mic is back with the high bid

Suckers you’ve lost cos players you’re not, gangstas you ain’t

You’re faintin’, punk, if you ever heard a gunshot

Yo, the pusher, the player, the pimp gangsta, the hustler

High Roller, dead pres folder

Is cold lampin’ like a black king on a throne

Evil E…turn up the microphone

So I can ill and break on the rollin’ tape

Another album to make? Great

Islam turn the bass kick up a bit

Hype the snare, now I got a place to sit

And ride the track like a black mack in his ‘lac

Hit the corner slow where the girls are at

And kick game the way it should be done

How you gonna drop science? You’re dumb

Stupid ignorant, don’t even talk to me

At school you dropped Math, Science and History

And then you get on the mic and try to act smart

Well let me tell you one thing, you got heart

To perpetrate, you’re bait, so just wait

Till the press shove a mic in your face

Or you meet Boogie Down or Chuck D

Stetsasonic or the Big Daddy

And they ask you about the game you claim you got

Drop science now, why not?

You start to sweat and fret, it gets hot

How’d you get into this spot?

You played yourself…

Yo, yo, you played yourself…

[Verse 2]

I’m no authority but I know the D-E-A-L

When it comes to dealin’ with the females

What you got they want, cash is what they need

Slip sucker and they’ll break you with speed

But you meet a freak, you try to turn her out

Spendin’ money’s what I’m talkin’ about

But you fool out, your pockets got blew out

And after the date, no boots, you got threw out

Mad and shook cos your duckets got took

Call her up, phone’s off the hook

But who told you to front and flaunt your grip?

You can’t buy no relationship

You played yourself…

Yo, homeboy, you played yourself…

[Verse 3]

I’m in the MC game, a lot of MC’s front

And for the money they’re sell out stunts

But they claim that they’re rich and that they keep cash

Yo, let me straighten this out fast

Two hundred thousand records sold

And these brothers start yellin’ ’bout gold?

You better double that, then double that again

And still don’t get sooped, my friend

You think you’ve made it, you’re just a lucky man

Guess who controls your destiny, fans

But you diss ’em cos you think you’re a star

That attitude is rude, you won’t get far

Cos they’ll turn on you quick, you’ll drop like a brick

Unemployment’s where you’ll sit

No friends cos you dissed ’em too

No money, no crew, you’re through

You played yourself…

That’s right, you played yourself…

You played yourself…

Yo, yo, you played yourself…

[Verse 4]

You got problems, you claim you need a break

But every dollar you get you take

Straight to the Dopeman, try to get a beam up

Your idle time is spent tryna scheme up

Another way to get money for a jumbo

When you go to sleep you count Five-O’s

Lyin’ and cheatin’, everybody you’re beatin’

Dirty clothes and you’re skinny cos you haven’t been eatin’

You ripped off all your family and your friends

Nowhere does your larceny end

And then you get an idea for a big move

An armed robbery…smooth

But everything went wrong, somebody got shot

You couldn’t get away, the cops roll, you’re popped

And now you’re locked, yo, lampin’ on Death Row

Society’s fault? No

Nobody put the crack into the pipe

Nobody made you smoke off your life

You thought that you could do dope and still stay cool? Fool.

You played yourself…

You played yourself…

Ain’t nobody else’s fault, you played yourself.

One reply on “The hidden world of aria-hidden”

I seem to recall that someone recently proposed that browsers should ignore aria-hidden on any element that receives focus. This seems like only a partial solution though, since that element may still not make a lot of sense if the surrounding context is also aria-hidden (and thus inaccessible).

I feel like it might actually make more sense if the content were still exposed via the a11y tree with a flag, allowing SRs the choice to still expose it (i.e., if the user enables a setting, or presses a certain key combination). Voiceover kinda does this already by ignoring aria-hidden if the user presses down/up arrows instead of VO + right/left arrow.

Leave a Reply

Your email address will not be published. Required fields are marked *