Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Semantic mark-up and WAI-ARIA for Tabbed Section?

I'm in the process of marking up a site and I've been really trying to hone my accessibility skills. I'm wondering what the most semantic mark-up is for tabbed content. This is what I have now:

<section>
  <nav>
    <a href="#tab" aria-controls="content">Stuff</a>
    <a href="#tab" aria-controls="content">Stuff</a>
    <a href="#tab" aria-controls="content">Stuff</a>
  </nav>
  <section id="content" aria-live="polite" role="region">
    <article>...</article>
    <article>...</article>
    <article>...</article>
   </section>    
</section>

I have a few specific questions about this.

  1. Am I on the right track? If not can someone recommend some changes?
  2. Will I need to make changes if I were to load in the articles via AJAX?
  3. Do I need the nav tag?
  4. Are WAI-ARIA roles enough here?
  5. Are these the correct WAI-ARIA roles to use?
like image 686
Jeffpowrs Avatar asked Oct 05 '13 22:10

Jeffpowrs


2 Answers

1.Am I on the right track? If not can someone recommend some changes?

Yes, you've absolutely started in a good way. Some of the tab stuff could be given some tab-related roles if you want to improve it, but it's functional as is.

2.Will I need to make changes if I were to load in the articles via AJAX?

No. It should be fine. The fact that it is a live region should (tested with NVDA only) mean that new content is announced. Is this the behaviour you're after?

3.Do I need the nav tag?

No, but I think it helps make it crystal clear what that bit of the document is for. A note though, that if you do what I've done below and mark it as a tablist, the fact that it's a navigation element doesn't get announced anymore.

4.Are WAI-ARIA roles enough here?

If by ARIA roles you're also including states and properties, yes essentially you should be covered for loading dynamic content (if that's what you're after). There's no case for moving the user's keyboard focus or anything with things as they are. IMO, you'd only really want to do that if there's a lot of navigational stuff between what the user clicked and what content you're giving them.

5.Are these the correct WAI-ARIA roles to use?

You're not far off. If you really want a tab-style experience, then you need the tablist, tab and tabpanel roles. I'll give an example.

I've taken your code and made a contrived but working example to test it. It's not loading anything in AJAX, just showing and hiding stuff. I wanted to be sure before I gave this answer, but I'll put the code here too in case it helps.

<html>
    <head>
        <title>Aria test</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                $('nav a').on('click', function () {
                    hideArticles();
                    deslectAllTabs();
                    $(this).attr('aria-selected', true);
                    var tab = '#' + $(this).attr('aria-controls');
                    $(tab).show();
                });
            });

            function hideArticles() {
                $('article').hide();
            }
            function deslectAllTabs() {
                $('nav a').attr('aria-selected', false);
            }
        </script>
        <style type="text/css">
            article { display: none; }
        </style>
    </head>
    <body>
    <section>
        <nav role="tablist">
            <a href="#tab" aria-controls="content1" id="tab1" role="tab">Stuff1</a>
            <a href="#tab" aria-controls="content2" id="tab2" role="tab">Stuff2</a>
            <a href="#tab" aria-controls="content3" id="tab3" role="tab">Stuff3</a>
        </nav>
        <section id="content" aria-live="polite" role="region">
            <article id="content1" role="tabpanel">The lazy dog jumped over the quick fox</article>
            <article id="content2" role="tabpanel">If you click this tab then your life will be better</article>
            <article id="content3" role="tabpanel">Know your roles</article>
        </section>    
    </section>
    </body>
</html>

I hope this helps.

like image 174
Craig Brett Avatar answered Oct 21 '22 06:10

Craig Brett


Semantics tend to get vague at this level, but yeah I think you're on the right track as long as each of the tabs would really count as a separate article.

The article element represents a component of a page that consists of a self-contained composition in a document, page, application, or site and that is intended to be independently distributable or reusable, e.g. in syndication. This could be a forum post, a magazine or newspaper article, a blog entry, a user-submitted comment, an interactive widget or gadget, or any other independent item of content.

Source

I don't think the <nav> is misplaced here, although it depends on how important the different tabs are in regards to the whole of your website:

The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links. Not all groups of links on a page need to be in a nav element only sections that consist of major navigation blocks are appropriate for the nav element. In particular, it is common for footers to have a list of links to various key parts of a site, but the footer element is more appropriate in such cases, and no nav element is necessary for those links.

Source

I wouldn't use sections to wrap the stuff in it though.

The section element is not a generic container element. When an element is needed only for styling purposes or as a convenience for scripting, authors are encouraged to use the div element instead. A general rule is that the section element is appropriate only if the element's contents would be listed explicitly in the document's outline.

Source

An additional rule of fist for the <section> element is that they should have a title. If not, it's probably not really a "section" but just a group of elements that you needed to wrap in something, so just use a <div>.

like image 23
Stephan Muller Avatar answered Oct 21 '22 08:10

Stephan Muller