dotjay.com / lab / tests / tabindex-firefox

Test cases for tabindex bugs in Firefox

Last updated: November 19, 2008

If you find any of the information useful, or if you find anything to be incomplete or inaccurate, please let me know.

Summary

A series of tests investigating problems with the tabindex attribute in the Firefox web browser.

As the tabindex attribute is only a valid attribute for a, area, button, input, object, select and textarea elements, some of these tests may seem to be breaking the W3C specification (e.g. where tabindex is applied to <div> elements). However, there is a rule in the specification that states:

“Those elements that do not support the tabindex attribute or support it and assign it a value of "0" are navigated next. These elements are navigated in the order they appear in the character stream.”

The language used there can make it confusing to read, but it is assumed that any element may be given a tabindex of "0" so that it may receive focus. Hence, tabindex="0" is used in the wild to attempt to make normally non-focusable elements appear in the tab order of a page (jQuery Accordion example). Browsers permit focus behaviour on non-supporting elements, but with some unexpected results in Firefox.

Summary of observations:

  1. A normally focusable child does not appear in the tab order if its parent has tabindex="0" and it is the first (or only) child of the parent. The child element is skipped over when tabbing forwards through the page (test 13 best demonstrates this). Now filed as bug 461982.
  2. The parent element with tabindex="0" traps keyboard navigation when tabbing backwards through the page (test 13 best demonstrates this). Now filed as part of bug 461982, but is related to bug 320407.
  3. A normally focusable immediate child of an element with tabindex="-1" is skipped over when tabbing forwards through the page after receiving focus from a link activated with the Enter key (test 4 best demonstrates this).
  4. The object element does not have an implied tabindex of "0" (test 14 best demonstrates this). Previously filed as bug 88140.

Methodology

Test cases tested using Firefox 3.0.3 on Mac OS X and Windows XP Pro SP 2. The Tab key is used to progress forwards through focusable elements of the page forwards and Shift+Tab to move backwards through those elements. </div> are used to enclose tests for convenience, but you can see the problems observed on different markup structures in the later tests below.

To maintain valid markup, tabindex is modified throughout using JavaScript. The test results are the same when setting the tabindex directly in the markup but results in invalid HTML.

Tests

Test 1

<div><a>link text</a></div>

A normal heading as a link.

Works as expected. The <a> can be tabbed through as normal both forwards and backwards.

Test 2

<div tabindex="0"><a>link text</a></div>

Weirdness.

The <div> can be tabbed through in the forward direction, but you cannot move backwards from the <div> element.

The <a> inside the <div> is skipped over when tabbing forwards, but can be accessed when moving backwards.

Test 3

<div><a tabindex="0">link text</a></div>

Works as expected. The <a> can be tabbed through as normal both forwards and backwards.

Test 4

<div tabindex="-1"><a>link text</a></div>

This test almost works as expected. The <a> receives focus when tabbing forwards and backwards. The <div> is not in the tabbing cycle, but it can be focussed using JavaScript or by clicking it with a mouse. When that JavaScript link is clicked, focus shifts to the heading and we can continue to tab to the <a> within the heading. Weirdly, navigating to that same link and activating it with the Enter key to focus the heading results in the <a> being skipped over when tabbing onwards (test 16 shows this doesn't happen when a link is not the first child of the element).

Test 5

<div>heading with <a>a link</a> inside</div>

Works as expected. The <a> can be tabbed through as normal both forwards and backwards.

Test 6

<div tabindex="0">heading with <a>a link</a> inside</div>

Works as expected. The <a> can be tabbed through as normal both forwards and backwards. Hang on a minute! So, adding tabindex="0" does not affect the child link if it is in the middle of the heading text. Comparing this to test 2, dropping the link between text nodes makes everything work. Let's investigate further…

Test 7

<div tabindex="0"><a>a link at the beginning</a> of the heading</div>

Weirdness again.

We're seeing the same problem as in test 2. So, Firefox acts up if the immediate child of the heading is an anchor (or any normally focusable element, in fact).

Test 8

<div tabindex="0">heading with <a>a link at the end</a></div>

Works as expected. Okay, so it's just an immediate focusable child of a parent element with tabindex="0" that is skipped, but otherwise you're fine.

Let's do some further tests for the avoidance of doubt…

Test 9: a different block-level element

<h4 tabindex="0"><a>a link at the beginning</a> of a block-level element</h4>

Weirdness.

Test 10: an inline element

<span tabindex="0"><a>a link at the beginning</a> of an inline element</span>

Weirdness.

Test 11: a different type of focusable child element (control)

<div><input> at the beginning of an element</div>

Works as expected.

Test 12: a different type of focusable child element

<div tabindex="0"><input> at the beginning of an element</div>

Weirdness.

Test 13: two links, one an immediate child of the test element with tabindex="0" applied to it

<div tabindex="0"><a>a link at the beginning is skipped</a><a> but this one receives focus</a></div>

Weirdness.

We're seeing the same problem as in test 2 for the first link, but not the second link. When tabbing forwards, the <div> is tabbable, the first link is skipped over and the second link receives focus. When tabbing backwards, we can tab through both links and the heading, but you cannot move backwards from the <div> element.

Test 14: a focusable child within a focusable parent element (control)

<object><a>a link at the beginning</a><a> and one after</a></object>

The links inside the element work as expected, but the object does not seem to have an implied tabindex of "0" as it should according to the HTML specification. However, it is arguable that there is no need to tab to an object element.

Test 15: a focusable child within a focusable parent element

<object tabindex="0"><a>a link at the beginning is skipped</a><a> but this one receives focus</a></object>

Works as expected. Note: tabindex is a valid attribute for the object element.

Test 16

<div tabindex="-1">heading with <a>a link</a> inside</div>

Works as expected.

The <a> receives focus when tabbing forwards and backwards. The <div> is not in the tabbing cycle, but it can be focussed using JavaScript or by clicking it with a mouse. In contrast to test 4, focus shifts to the heading and we can continue to tab to the <a> within the heading whether the link is clicked or activated with the Enter key.

bugzilla.mozilla.org

Back to the Tests index.

Back to the Lab index.

Page last updated: November 19, 2008