Varvara Stepanova
Varvara Stepanova

Reputation: 3569

VoiceOver (Mac) navigates with tabindex and ignore aria- attributes

How do I make a VoiceOver on Mac read the aria-label (or another aria- attributes) with no conflict with tabindex?

I am trying to provide some accessibility stuff to a search result page with the structure like this

    <div class="header">
        <input value="" name="search" type="search"/>
    </div>
    <div class="main">
        <div class="adv-block">
            <a href="#">Link to adv 1</a>
            <a href="#">Link to adv 2</a>
        </div>
        <div class="search-result">
            <a href="#">Search result 1</a>
            <a href="#">Search result 2</a>
        </div>
    </div>

First, I want a user with tab navigation skip advertisments, so I provide tabindex for and input and then for the search results, like this.

    <div class="header">
        <input value="" name="search" tabindex="1" type="search"/>
    </div>
    <div class="main">
        <div class="adv-block">
            <a href="#">Link to adv 1</a>
            <a href="#">Link to adv 2</a>
        </div>
        <div class="search-result">
            <a href="#" tabindex="2">Search result 1</a>
            <a href="#" tabindex="3">Search result 2</a>
        </div>
    </div>

But then I would like to help screen reading programme (in my case a VoiceOver on Mac) to read the zones correctly. So, I mark the search results contaiter with its role and description.

    <div class="header">
        <input value="" name="search" tabindex="1" type="search"/>
    </div>
    <div class="main" role="main" aria-label="Search results">
        <div class="adv-block">
            <a href="#">Link to adv 1</a>
            <a href="#">Link to adv 2</a>
        </div>
        <div class="search-result">
            <a href="#" tabindex="2">Search result 1</a>
            <a href="#" tabindex="3">Search result 2</a>
        </div>
    </div>

The problem is that VoiceOver also navigates according to tabindex and it goes from the input directly to the first link.

I tried to cheat with adding a tablindex attribute to the container

    <div class="header">
        <input value="" name="search" tabindex="1" type="search"/>
    </div>
    <div class="main" role="main" aria-label="Search results" tabindex="2">
        <div class="adv-block">
            <a href="#">Link to adv 1</a>
            <a href="#">Link to adv 2</a>
        </div>
        <div class="search-result">
            <a href="#" tabindex="3">Search result 1</a>
            <a href="#" tabindex="4">Search result 2</a>
        </div>
    </div>

But this cases changes for a usual tab navigation.

So, is there a way to make VoiceOver read that a user proceeded to a search result zone?

Upvotes: 2

Views: 3401

Answers (2)

Jonathan Leitschuh
Jonathan Leitschuh

Reputation: 868

The current w3 accessibility standard says to try to avoid using positive tabindex values. It is best practice to layout your dom so that you can simply use tabindex=0 for everything that should be tabbable to.

Upvotes: 0

AlastairC
AlastairC

Reputation: 3297

Please be very careful when trying to force a particular navigation style, as tabbing is not the only (or even primary) method of navigating with a screen reader.

Most of the time a screen reader user would use 'browse' navigation to read the content. On VoiceOver this is cntl-alt-right arrow, in Jaws/NVDA it is just down-arrow.

Browse mode will go through all content, not just form controls and links. Browse mode is not affected by tabindex.

The problem with tabindex is that it over-rides the default (code) order, which can be very confusing when it doesn't match the browse order. This is more obvious when there are other things in the page, and then you skip chunks of content and go to the lowest tabindex.

I would recommend something like:

<header role="banner">
  <div class="header" role="search">
    <label for="search" class="hidden">Search</label>
    <input value="" name="search" type="search" id="search">
  </div>
</header>
<div class="adv-block">
     <a href="#">Link to adv 1</a>
     <a href="#">Link to adv 2</a>
</div>
<main role="main" id="main" aria-labelledby="results">
    <h1 id="results" class="hidden">Search results</h1>
    <div class="search-result">
        <a href="#" tabindex="2">Search result 1</a>
        <a href="#" tabindex="3">Search result 2</a>
    </div>
</main>

NB: I am assuming there will be other stuff to go into the header, otherwise it wouldn't be worth using the header with banner role.

Typical ways that people using screen readers get to the 'content' are:

  • Arrow down through everything, time consuming but reliable.
  • Skip by heading (cntl-alt-cmd-h in VoiceOver), and the main heading 1 is a good indicator of the primary content of the page.
  • Open the landmarks dialogue (cntl-alt-u and then left/right to find it in VO) and go to the 'main' landmark.
  • Tabbing through links, and consistency trumps efficiency here.

Overall I would recommend against trying to manipulate the tab-order, and make sure you provide good headings, landmarks, and maybe a skip-link if you really need to provide a short-cut. This applies to Windows based screen readers as well.

Upvotes: 2

Related Questions