I recently implemented some functions for Dojo for getting, setting, and removing tabindex values. It’s not entirely straightforward — here’s what I found out:

Browsers tested

  • Internet Explorer 6 on Windows XP
  • Internet Explorer 7 on Windows XP
  • Firefox 2 on Windows XP
  • Firefox 3 beta3pre (the Minefield nightly build of 2008-01-07) on Windows XP
  • Safari 3.0.4 on Mac OS X 10.5.1
  • Opera 9.25 on Windows XP

Getting the tabindex value from an element

Element.tabIndex and Element.getAttribute("tabindex") can be used to get the tabindex value on both HTML and XHTML documents:

input with tabindex=”1″ IE6 IE7 FF2 FF3 HTML Safari 3 HTML Opera 9 HTML FF2 FF3 XHTML Safari 3 XHTML Opera 9 XHTML
elem.tabIndex 1 1 1 1 1 1 1
elem.getAttribute(“tabindex”) 1 1 1 1 1 1 1
elem.getAttribute(“tabIndex”) 1 1 1 1 null null null

Element.getAttribute("tabIndex") can be used to get the value on HTML documents. However, Firefox, Safari, and Opera treat XHTML documents case-sensitively and, when used on an XHTML document, Element.getAttribute("tabIndex") will return null.

Getting the tabindex value on an element that doesn’t have one explicitly set

On elements allowed to have tabindex attributes in HTML4, the tabIndex property defaults to 0 when no tabindex has been explicitly set:

input with no tabindex IE6 IE7 FF2 FF3 Safari 3 Opera 9
elem.tabIndex 0 0 0 0

On elements not allowed to have tabindex attributes in HTML4 (but supported by IE and Firefox and the upcoming HTML5), the tabIndex property defaults to 0 on Internet Explorer, -1 on Firefox, and undefined on Safari 3 and Opera 9:

div with no tabindex IE6 IE7 FF2 FF3 Safari 3 Opera 9
elem.tabIndex 0 -1 undefined undefined

On Internet Explorer, Element.getAttribute("tabindex") returns 0 on elements that have no tabindex value explicitly set. The other browsers return null:

div with no tabindex IE6 IE7 FF2 FF3 Safari 3 Opera 9
elem.getAttribute(“tabindex”) 0 null null null

Testing if tabindex has been set on an element

On Internet Explorer we can’t use Element.getAttribute("tabindex") to determine if a tabindex has been specified on an element because it returns 0 even when one hasn’t been. IE also doesn’t implement Element.hasAttribute(). However, IE6 and IE7 do implement Element.getAttributeNode() and we can use that (Element.getAttributeNode() is also available on Firefox, Safari, and Opera.) When it is called on Internet Explorer on an element with no tabindex value set, Element.getAttributeNode() will return a node whose specified property is false. When called on Firefox, Safari, and Opera it will return null. For cross-browser compatibility, we can use a test like this:

var attr = elem.getAttributeNode("tabindex");
return attr ? attr.specified : false;

Setting the tabindex value on an element

Element.setAttribute("tabIndex") must be used on Internet Explorer. Either “tabindex” or “tabIndex” can be used for HTML on Firefox, Safari, and Opera, but “tabindex” must be used for XHTML:

input element IE6 IE7 FF2 FF3 HTML Safari 3 HTML Opera 9 HTML FF2 FF3 XHTML Safari 3 XHTML Opera 9 XHTML
elem.setAttribute(“tabindex”) N Y Y Y Y Y Y
elem.setAttribute(“tabIndex”) Y Y Y Y N N N

Removing the tabindex value from an element

Like setAttribute(), Element.removeAttribute("tabIndex") must be used on Internet Explorer and either “tabindex” or “tabIndex” can be used for HTML on Firefox, Safari, and Opera. “tabindex” must be used for XHTML:

input element IE6 IE7 FF2 FF3 HTML Safari 3 HTML Opera 9 HTML FF2 FF3 XHTML Safari 3 XHTML Opera 9 XHTML
elem.removeAttribute(“tabindex”) N Y Y Y Y Y Y
elem.removeAttribute(“tabIndex”) Y Y Y Y N N N

Test files, detailed results, and Dojo implementation

Updated 2008-01-10: corrected removeAttribute(“tabIndex”) results

11 Responses to “Getting, setting, and removing tabindex values with JavaScript”

  1. zcorpan says:

    > Either “tabindex” or “tabIndex” can be used [for removeAttribute, including for XHTML] on Firefox, Safari, and Opera:

    This doesn’t seem to be the case. removeAttribute is case-sensitive in XML just like setAttribute.

    Your test case is incorrect since it first removes the ‘tabindex’ attribute, then checks the presence of the ‘tabindex’ attribute, then removes the (non-existent) ‘tabIndex’ attribute and checks the presence of the ‘tabindex’ attribute again.

  2. simon says:

    @zcorpan: thanks very much for your catch. I’ve updated the post and my test cases.

  3. Note that Opera 9.5 does support the tabindex attribute on all elements, just like Internet Explorer and Firefox.

  4. [...] follow up to Simon’s recent posting about the intricacies of cross-browser support for the tabindex attribute, I’ve written a jQuery plugin that makes it easy to get, set, and check for the presence of [...]

  5. [...] interested in creating similar widgets should note that getting, setting, and removing tabindex values with JavaScript in a cross browser friendly way requires some additional [...]

  6. [...] Damit der Screenreader die Rolle sowie Eigenschaften des jeweils aktiven Widget-(Unter-)Elements begreifen kann, muss dieses – insbesondere wenn es Interaktionsmöglichkeiten bietet – in der Regel fokusiert werden. Um die Fokusierbarkeit bei allen Elementen zu ermöglichen, wurde das tabindex-Attribut zum Universalattribut deklariert. Bekommt das tabindex-Attribut den Wert „0“, ist es in der normalen Tabreihenfolge durch den User fokussierbar. Hat es dagegen den Wert „-1“, liegt es außerhalb der Tabreihenfolge, kann jedoch vom Autoren mit JavaScript fokussiert werden (Bei Aria-Widgets für „Unterelemente“ der Normalfall.). (Näheres zum Setzen/Auslesen des tabdindex per JavaScript.) [...]

  7. George says:

    I believe IE6/7 place the focus by default in the browser controls, not in the content area. If an element calls focus() these browsers respect this call and yield focus to that element. However, if an element sets its tabIndex to 1 and no other elements have a higher tabIndex, these browsers force the user to tab through 7 browser control fields (“Chrome”) prior to allowing that element to get focus. I have been unable to find a way to take focus away from the Chrome such that a single tab key press takes the user immediately to the desired field.

    Putting focus on a field in the content area does indeed take focus away from the Chrome but for some reason then the browser does not respect tab order, so using a combination of focus() and tabIndex = 1 does not seem to work.

  8. ???? says:

    [...] ??input?type???????????????form???getAttributeNode????????action?Dom0??????????????????tabIndex??????????????????????Getting, setting, and removing tabindex values with JavaScript????????style?opacity???????????????????????????jQuery.attr??????????????????????????? [...]

  9. Bodselofs says:

    hm. really like it ))

  10. [...] } jQuery’s comments include a reference to more details on handling this: Getting, setting, and removing tabindex values with JavaScript.ConclusionWhen I started writing this article I thought getting attributes would just be a case of [...]

Leave a Reply