HTML5

February 20, 2012

HTML5 Accessibility: aria-hidden and role=”presentation”

The Use Case

It’s a common design pattern, seen multiple times a day: a thumbnail image and Headline, both linked to the same URL. We’ve seen this pattern for so long now that most sighted users know, instinctively, that clicking on either the thumbnail or the Headline takes them to the same location.

duplicate

However the code developers use to achieve this is a bit of a mess, and for non-sighted users or keyboard-only users, the User Experience (UX) leaves a lot to be desired: duplicate links announced for each article, and excessive tabbing through the content. Since the image links to the same location as the headline, the current recommendation for appropriate alt text for the image should be the same text as the headline:

When an a element that is a hyperlink, or a button element, has no text content but contains one or more images, the alt attributes must contain text that together convey the purpose of the link or button.
HTML5: Techniques for providing useful text alternatives

Because the “headline” is actually a Heading, the anchor element MUST be contained inside of the Heading element to validate, resulting in the following code:

While this allows sighted users to click on either the image or the Headline, the user-experience for non-sighted users is a duplication of links being voice aloud, and for keyboard only users twice as many tab stops to navigate through.

It would appear that either aria-hidden="true" or role="presentation" should be able to help out here.

Defining aria-hidden

The W3C WAI-ARIA 1.0 Candidate Recommendation provides the following normative information:

aria-hidden: Indicates that the element and all of its descendants are not visible or perceivable (i.e.presentable to users in ways they can sense) to any user as implemented by the author. (See related aria-disabled).

Authors MAY, with caution, use aria-hidden to hide visibly rendered content from assistive technologies only if the act of hiding this content is intended to improve the experience for users of assistive technologies by removing redundant or extraneous content. Authors using aria-hidden to hide visible content from screen readers MUST ensure that identical or equivalent meaning and functionality is exposed to assistive technologies.

In my opinion, the ARIA spec language could/should be clarified here to underscore the fact that it is not “any” user, but rather any user accessing the Accessibility API. As well, while the spec does suggest a direct relationship could be drawn between this attribute and CSS {visibility: hidden;}, it also leaves open the possibility of it NOT having that kind of direct mapping, as in the use case illustrated here.

Defining role=”presentation”

presentation (role): An element whose implicit native role semantics will not be mapped to the accessibility API.

The intended use is when an element is used to change the look of the page but does not have all the functional, interactive, or structural relevance implied by the element type, or may be used to provide for an accessible fallback in older browsers that do not support WAI-ARIA.

Example use cases:

  • An element whose content is completely presentational (like a spacer image, decorative graphic, or clearing element);
  • An image that is in a container with the img role and where the full text alternative is available and is marked up with aria-labelledby and (if needed) aria-describedby;
  • An element used as an additional markup “hook” for CSS; or
  • A layout table and/or any of its associated rows, cells, etc.

A careful reading of the spec surfaces a bit of a problem: (tab) focusable elements are not intended to be presentational only, which actually makes sense.

Running some tests

Armed with some normative definitions, I decided I would run a few tests to see if either or both of these ARIA attributes could solve the problem. The full test suite and results are posted at http://john.foliot.ca/html5/aria-hidden, but a summary of the results follows.

  • Test 1: aria-hidden=”true” on anchor element (with <img alt=””>)
  • Test 2: aria-hidden=”true” on both anchor element and image (with <img alt=””>)
  • Test 3: aria-hidden=”true” on anchor element (with <img alt=”_value”>)
  • Test 4: aria-hidden=”true” on both anchor element and image (with <img alt=”_value”>)
  • Test 5: role=”presentation” on anchor element (with <img alt=””>)
  • Test 6: role=”presentation” on both anchor element and image (with <img alt=””>)
  • Test 7: role=”presentation” on anchor element (with <img alt=”_value”>)
  • Test 8: role=”presentation” on both anchor element and image (with <img alt=”_value”>)
  • Test 9: aria-hidden=”true” on anchor element + role=”presentation” on both anchor and image elements (with <img alt=”_value”>)
  • Test 10: aria-hidden=”true” & tabindex=”-1″ on anchor element + role=”presentation” on both anchor and image elements (with <img alt=”_value”>)
  JAWs NVDA Chrome
Vox
Voice
Over
Firefox 10 IE 9 IE 8 Chrome Firefox 10 IE 9 IE 8 Chrome Chrome Safari
  Firefox 10 IE 9 IE 8 Chrome Firefox 10 IE 9 IE 8 Chrome Chrome Safari
JAWs NVDA Chrome
Vox
Voice
Over
aria-hidden=”true”
Test 1 Pass Fail Fail Pass Fail Fail Fail Pass Pass Pass
Test 2 Pass Fail Fail Pass Fail Fail Fail Pass Pass Pass
Test 3 Pass Pass Pass Pass Fail Fail Fail Pass Pass Pass
Test 4 Pass Pass Pass Pass Fail Fail Fail Pass Pass Pass
role=”presentation”
Test 5 Pass Pass Pass Pass Fail Fail Fail Pass Pass Pass
Test 6 Pass Pass Pass Pass Pass Fail Fail Pass Pass Pass
Test 7 Warning Warning Warning Warning Pass Warning Warning Warning Pass Warning
Test 8 Pass Pass Pass Pass Pass Pass Pass Pass Pass Pass
aria-hidden=”true” + role=”presentation”
Test 9 Pass Pass Pass Pass Pass Pass Pass Pass Pass Pass
Test 10 Pass Pass Pass Pass Pass Pass Pass Pass Pass Pass

Observations

aria-hidden

I was actually surprised about the level of support I found with Internet Explorer (both 8 & 9), although when the ALT text was not provided (alt=””) JAWs/IE did some heuristic remedial work, and did not remove the image from the flow. However when a text string was provided, it silenced the fact that the image and link was there – go figure.

I also confirmed that at this time NVDA is not supporting this ARIA attribute: I have filed a bug with the development team after reading through their bug tracking system. A concern raised by the NVDA team is the question of inheritance, and what happens if an author changes the aria-hidden value of a child element:

Re-reading the spec language, it states:

the element and all of its descendants are not visible

with no other mention, so I would assume that the above is a non-valid anti-pattern. Perhaps some clarity in the spec around this question is required. Further, in conversation with Victor Tsaran (Yahoo!) we could not come up with a reasonable use-case where that might appear – if you can think of one please let us know. The good news is that James Teh from NVDA indicated that they could likely start supporting aria-hidden (in this fashion) without too much effort. Fingers crossed.

Support in Chrome (via ChromeVox, JAWs and surprisingly NVDA) was solid, as was VoiceOver on both iOS and OS X – no surprises there.

role=”presentation”

I was a little unsure about using this attribute here, in part because I am a little confused about what the spec is saying exactly – by my reading there is some confusion over what to do with focusable content. Specifically, the spec states:

For any element with a role of presentation and which is not focusable, the user agent MUST NOT expose the implicit native semantics of the element (the role and its states and properties) to accessibility APIs. However, the user agent MUST expose content and descendant elements that do not have an explicit or inherited role of presentation.

…yet earlier it also states

The intended use is when an element is used to change the look of the page but does not have all the functional, interactive, or structural relevance implied by the element type.

Where does this leave the anchor element as a hyperlink (<a href>), which is normally a focusable element? Should the link be deactivated, but the contained content remain? This appears to be the case, which Test 7 confirms. However it appears that at least NVDA is not treating anchor tags like this, at least not fully: while the ‘link’ is concealed from the Accessibility Tree, NVDA none-the-less does a heuristic repair on the image element and instead of treating alt=”” as silent, it announced a truncated name (here TBL, taken from the html file-name: tbl.html). While I can understand why NVDA would do this type of heuristic repair under other circumstances, I was disappointed that it did not respect the alt=”” here, given that the anchor tag does not have all the functional, interactive, or structural relevance implied by the element type. However, given the slight ambiguity in the spec at this time, I am not 100% sure if a bug needs to be filed at this time, although my suspicion is yes. What do you think?

I was a little surprised at how poorly ChromeVox did on these tests, but will chalk them up to the previously noted ambiguity. VoiceOver on the other hand did quite well, and given that James Craig works on accessibility at Apple, and has been directly involved in the ARIA specs as Editor, I look at Apple’s implementation as likely being the intended outcome.

Tab focus

One of my goals was to also try and take the thumbnail link out of the tab focus; which was not very successful. While I reported that the aria-hidden and role=”presentation” often silenced the screen readers, tabbing through the page still resulted in the tab-stop applied to the image, which was awkward at best and not very user-friendly to keyboard-only users: in fact it was only when I applied tabindex="-1" to the anchor element did I get the result I was looking for (and even then, without support in either IE 8 or 9 – perhaps 10?).

Is this correct behavior? Should content that is either “hidden” or simply “presentational” still take a tab-stop? I personally don’t believe so, but I am curious to hear your opinions.

Solution / Conclusion

In the end, I was able to come fairly close to my goal. It is unfortunate that Internet Explorer remains as behind as it is, while at the same time holding out great promise for IE 10. I really hope they don’t let us down this time. For those of you looking for the quick and dirty solution, here’s what worked best for me:

I would like to thank Victor Tsaran, Pratik Patel, and Artur Ortega for their feedback and testing assistance in this project.

CC BY-NC-SA 4.0
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Posted by John

I am a 15 year veteran of Web Accessibility, living and working in the Bay Area. I am also actively involved with the W3C - the international internet standards body - where I attempt to stir the pot, fight hard for accessibility on the web, and am currently co-chairing a subcommittee on the accessibility of media elements in HTML5.

View more posts from this author

Leave a Reply