Creating Logical Tab Order with the Tabindex Attribute

From WCAG WG

Technique Category

Technique Status Category

Status

Techniques Proposed

Applicability

HTML5

WCAG references

This technique relates to:

User Agent and Assistive Technology Support Notes

Older browser versions might not support tabindex on non-focusable elements, nor a tabindex value less than 0.

Description

The objective of this technique is to provide a logical tab order in cases where the default tab order is not sufficient to meet the author's needs. Often, G59: Placing the interactive elements in an order that follows sequences and relationships within the content is sufficient to create a logical tab order. In such cases, it is preferable to use the default tab order and avoid explicitly setting tabindex values. Explicitly setting tabindex values can easily introduce usability bugs.

In some cases, however, the author may want to specify a tab order which follows relationships in the content without following the reading order of the elements in the code. Furthermore, default tab order includes only interactive elements, such as form controls and links. The author may want to include non-interactive elements in the tab order. In such cases, the tab order can be set explicitly using the tabindex attribute for any element.

Tabindex can also be used as a means to allow focus to be sent to components such as dialogs and menus, whose location in the DOM is not adjacent to their respective trigger controls. In such cases, focus can be sent via scripting to the relevant component, where that component's container element, or one of its child elements, has a tabindex value. This will allow the logical tab order to be maintained, while also dynamically correcting the reading order of the page.

Three behaviors are defined for the tabindex attribute. If the value is a negative integer, the element can be focused, but is not reached using sequential focus navigation. If the value is 0, the element will be included in sequential focus navigation without being given special preference in the tab order. If the value is a positive integer, the element will be included in sequential focus navigation and have a tab order preference relative to its value.

Note: Explicitly setting the tab order with the tabindex attribute will usually not correct the programmatically determined reading order. Success criterion 1.3.2 requires that the reading order be correct regardless of the tab order. This technique only allows authors to set a tab order which will aid keyboard users to navigate the page in a preferred sequence. In addition to a logical tab order, authors must make sure that the programmatically determined reading order is maintained. See Example 3 below for a proper implementation of reading order.

Examples

Example 1

A Web page contains a search field in the upper right corner. It is given a tabindex value of "1" so that it will receive focus, and occur first in the tab order, even though it is not first in the content reading order.

<h2>Search this site</h2>
<input tabindex="1" type="text" title="Search Site" />

Example 2

A web page contains a long article with numerous sections of reading content. The page allows the user to navigate the sections with the keyboard. Each paragraph is assigned a tabindex of "0", thus including them in the sequential focus navigation of the page.

<p tabindex="0">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in ...</p>
<p tabindex="0">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit ...</p>

Example 3

A web page implements a modal dialog via scripting. It appears visually in the center of the page, but is located at the end of the DOM in the source code. The dialog consists of a header, message text, and a close button. By default, the dialog is given a style of "display: none". When activated, it is shown to users. Since the dialog is not adjacent to the users current position in the tab order, the author sends focus to the dialog by doing the following:

  • Assigning a tabindex to the header of the dialog
  • Sending focus to that header element.

The user is then able to tab directly to the close button after reading the message. The tabindex given to the header has a value of "-1". This allows focus to be sent to the header element, but does not include it in the sequential focus navigation. After the user closes the dialog, focus is sent back to the control which triggered the dialog, thus allowing the user to continue tabbing through the page in a logical manner.

The following shows the code for the trigger control which opens the modal dialog:

<input id="btnSubmit" type="button" value="Submit" onclick="return sendAndValidateForm();" />

The following shows the code for the modal dialog:

<div id="divDialog" style="display: none">
<h2 id="dialogHeader" tabindex="-1">Alert!</h2>
<p><strong>Please provide answers to all required questions!</strong></p>
<input type="button" value="Close Dialog" onclick="returnToForm();return false;" />

The following functions in script open and close the dialog and send focus to the proper location. They are written in jQuery:

function openDialog()
{
 $('#divDialog').show();
 $('#dialogHeader').focus();
}
function closeDialog()
{
 $('#divDialog').hide();
 $('#btnSubmit').focus();
}

Resources

Related Techniques

Tests

Procedure

  1. Check if tabindex is used.
  2. If elements with a tabindex greater than 0 are present, check that the tab order for the page follows a logical and meaningful order.
  3. If components, such as menus and dialogs which are activated by a trigger control, are present on the page, and are not adjacent to their respective trigger controls, check that the container element, or one if its child elements, has a tabindex, that activation of the component sends focus to that element, and that the user can then tab through the component in a logical order.

Expected Results

  • #2 and #3 are true