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.

[Screen Capture: On-line news site, showing an image and headline, both linked to the same news story URL]

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:

<a href="tbl.html">
  <img src="tim_th.jpg" class="thumb" 
       alt="Tim Berners-Lee Takes the Stand to Keep the Web Free"></a>
<h3>
  <a href="tbl.html">Tim Berners-Lee Takes the Stand to Keep the Web Free</a>
</h3>

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 Fail Pass
Test 7 Warning Warning Warning Warning Fail Warning Warning Warning Fail Warning
Test 8 Pass Pass Pass Pass Pass Fail Fail Pass Fail Pass
aria-hidden=”true” + role=”presentation”
Test 9 Pass Pass Pass Pass Pass Fail Fail Pass Pass Pass
Test 10 Pass Pass Pass Pass Pass Fail Fail 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:

<div aria-hidden="true">
  <p aria-hidden="false">Some text here </p>
</div>

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:

<a href="tbl.html" aria-hidden="true" role="presentation" tabindex="-1">
  <img src="tim_th.jpg" class="thumb" 
       alt="Tim Berners-Lee Takes the Stand to Keep the Web Free"
       role="presentation"></a>
<h3>
  <a href="tbl.html">Tim Berners-Lee Takes the Stand to Keep the Web Free</a>
</h3>

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

"HTML5 Accessibility: aria-hidden and role="presentation"", out of 5 based on 4 ratings.

  1. #1 by stevefaulkner on February 21, 2012 - 3:35 am

    Hi John,
    note that JAWS has a heuristic that filters out duplicate links

    Filter consecutive duplicate links – This option controls whether consecutive links that point to the same location, one graphical and one text, are filtered. When selected, only the text link is announced. This check box is selected by default.

    • #2 by John on February 21, 2012 - 7:25 am

      Hi Steve,
      This simply serves to underscore that this is a real problem experienced by non-sighted users: the fact that JAWs applies a heuristic solution is useful for those users, but what of NVDA, Window-Eyes, VoiceOver, System Access… seems to me that if authors can address the problem in advance of serving it to their readers it would be a better solution.

  2. #3 by silvia on February 21, 2012 - 5:25 am

    Have you tried using aria-describedby to avoid the double speaking problem?

    • #4 by John on February 21, 2012 - 7:22 am

      Hi Silvia,
      I’m not sure what you mean here: both the headline and the image should share the same link text, as they both resolve to the same location. Having two different “link texts” resolving to the same location would be a terrible experience for non-sighted users: a link to “this” or a link to “that” would actually be the same thing.

  3. #5 by mraccess on February 21, 2012 - 7:37 am

    This is similar to the technique I use to ensure progressive enhancement/graceful degradation for ARIA based controls like page tabs that also contain off-screen text indicating role and active state.  For example, aria-hidden can be used to obscure the off-screen span in the case of
    <a href="…">Reports <span class="offscreen" aria-hidden="true"> – Active Tab </span> </a>

  4. #6 by www.google.com-accounts-o8-id-id-AItOawlmJVXSzJxD7YxuUZ4qjBvIaop6K8LwEO8 on February 21, 2012 - 9:35 am

    John,

    Great post.

    Wanted to respond to a few points. I generally don't think it's a good idea to hide content from a screen reader, but in this case it makes sense. An alternative would be to nest the link image inside of the h3. NVDA presents the image link and the bare anchor link as on the same "line" (down arrowing reads off both items in one shot) and is probably more representative of the visual layout of the page.

    This does seem like a good canidate for aria-flowto, aria-labelledby, etc given the right browser/screen reader support. I could imagine that, for example, aria-flowto could specify a document reading order that would skip elements like this; screen reader users seem likely to want to jump from headline to headline in this case.
     

  5. #7 by komputist on February 21, 2012 - 3:47 pm

     
    Super useful test results! However, there is one premise which is wrong — I cite:

    Because the “headline” is actually a Heading, the anchor element MUST be contained inside of the Heading element to validate

    This is actually not true. It was true, in HTML4. But it is not true in HTML5. In HTML5, one could wrap the anchor element around both the IMG element and the H3 element — resulting in a single link:
    <a href="tbl.html">
    <img src="tim_th.jpg" class="thumb" alt="">
    <h3>
    Tim Berners-Lee Takes the Stand to Keep the Web Free
    </h3>
    </a>
    Or this:
    <a href="tbl.html">
    <p>
    <img src="tim_th.jpg" class="thumb" alt="">
    <h3>
    Tim Berners-Lee Takes the Stand to Keep the Web Free
    </h3>
    </a>
     
    That said: It is perhaps the solution you have tested might actually be the best one. Because I suspect that it might not very vice to wrap both the IMG and the H3 inside the link — may be it would blur the 'headingness' of the H3 element — leading the AT to announce it as a link rather than as a heading. Well, another thing to test, I guess …. 

    • #8 by John on February 21, 2012 - 4:17 pm

      …yep, another thing to test. I believe more than anything else we need to start testing all of this stuff, and get it out of the realm of theory and into the realm of actual “what happens today”. To that end I have started doing exactly that, and am already working on another test suite: stand by for more details. (Also open to suggestions BTW)

  6. #9 by Umber on January 8, 2013 - 10:30 am

    Recently I studied the ARIA-spec and while I was also confused about focusable elements on role=presentation, I think I figured it out based on the context in which the spec places these attributes:
    I interpret it as follows:
    role=presentation is to be used on non-focusable, non-interactive elements only. When you think about it, that makes sense since anything that can have focus or can be interacted with, is not just presentation.
    If you want to remove something that can have focus or be interacted with, then use aria-hidden, which is described in the spec in context to interactive elements. Again it makes sense since the element is not presentation. Examples of this include images inside links or color-pickers in forms.

  7. #10 by MrB on May 22, 2013 - 2:56 am

    Thanks for this, it has helped me clarify whats what.

    I understand that in part this example could be somewhat contrived to explore these attributes behaviours, but I would always try to get what I want with the barest html and some css. Eg, to achieve the above I’d just have

    Link text

    Description

    And then with a little CSS jiggery make it all neat the webpage. No need to then try hiding an extra hyperlink

  8. #11 by MrB on May 22, 2013 - 2:59 am

    Arghh, no idea how to enter code; I’ll try

    <div>
    <h3>
    <a><img alt=”">Link text</a>
    </h3>
    <div>
    Description
    </div>
    </div>

You must be logged in to post a comment. Here's Why.