Accessibility 02 Jul 2009 01:27 pm

More Fun with the tabindex attribute

Back in November, 2007 I blogged my results of testing the tabindex attribute in several browsers. I recently retested with the latest versions of the browsers and included Safari 4. Luckily the recommended methods for working with the tabindex attribute do not change. Here is the updated version:

All you never wanted to know about tabindex

The tabIndex attribute can be used to allow nearly any element to be put into the tab order or receive focus programmatically. This has been implemented in Internet Explorer starting with version 5, Firefox starting with version 1.5, Opera 9.5 and Safari 4.
Being able to set focus to any element on the page is important for accessibility in order to implement full keyboard navigation. Elements that represent the intial interaction with a user interface component
can be but into the tab order. Other elements which are part of a particular user interface component can be interacted with via other key combinations. The keystroke interaction and identification of the user interface components to assistive technologies depends upon being able to set focus to these elements.

How Focus and tab key navigation work

  • Normally only input and anchor elements are put into the tab order of a page by default.
  • Setting a tabIndex attribute of 0 onto an element will put it into the tab order of the page and allow it to receive focus via the keyboard.
  • Setting a tabIndex of -1 on an element will allow the element to receive focus programmatically. For input and anchor elements, setting tabIndex of -1 will remove the element from the tab order and allow focus to only be set programmatically.
  • Setting a tabIndex of >0 onto an element will put that element sequentially into the tab order based on the tabIndex value. Elements with a positive tab index are put into
    the tab order before other elements with a tabIndex of 0 or which are in the tab order by default.

There are different behaviors for the tabIndex attribute and capitalization of the I makes a difference in how the attribute is interpretted in html and xhtml.
After testing different combinations of setting and querying the tabindex attribute, a set of best practices is outlined below followed by a table listing the results of each test.

Using tabIndex across browser and content type

  1. Always use tabindex with lowercase i in markup. See row 1 in table below.
  2. Use tabIndex with uppercase I when setting in script via element.tabIndex. See row 4 in table below.
  3. Check browser and/or content-type when setting in script via element.setAttribute()
    • if is IE or content-type is text/html - set via elem.setAttribute(tabIndex) uppercase. See row 6 in table below.
    • if is content-type application/xhtml+xml or not IE 6 or 7 - set via elem.setAttribute(tabindex) lowercase. See row 7 in table below
  4. Use lowercase when querying a value using getAttribute(tabindex) that was set in markup as lowercase. See row 9 in table below.
  5. Use lowercase when querying a value using getAttribute(tabindex) that was set directly on element using element.tabIndex uppercase. See row 15 in table below.
    Setting tabIndex directly on the element using element.tabIndex avoids having to check browser or content type when getting the value.
  6. If the rules above have been followed, use lowercase when querying a value using hasAttribute(tabindex) where available. See rows 25, 31 and 33 in table below.

Simplified Rules

  • use tabindex lowercase to set in markup
  • use element.tabIndex with uppercase I to set in script
  • query via getAttribute(tabindex) lowercase

TabIndex testing results

The following table shows the results of testing on Windows with Internet Explorer versions 6, 7, and 8, Firefox 2.0.0.20, Firefox 3.0.1, Firefox 3.5, Opera 9.64 and Safari 4.
IE 6, 7, 8 where tested using HTML 4.01 strict. Firefox 2, 3, 3.5 as well as Opera and Safari were tested with HTML 4.01 strict as well as with XHTML 1.0 strict
served with content-type of application/xhtml+xml. Unless otherwise noted, a div was used as the test element.

 IE 6/7 IE 8 HTML FF 2/3/3.5, Opera 9.64, Safari 4 HTML FF 2/3/3.5, Opera 9.64, Safari 4 XHTML
1 tabindex set in markup (lowercase) yes yes yes yes
2 tabIndex set in markup (uppercase) yes yes yes no
3 tabindex set via elem.tabindex (lowercase) no no no no
4 tabIndex set via elem.tabIndex (uppercase) yes yes yes yes
5 tabindex set via setAttribute(tabindex) (lowercase) no yes yes yes
6 tabIndex set via setAttribute(tabIndex) (uppercase) yes yes yes no
7 query elem.tabIndex uppercase when set as 0 in markup as lowercase 0 0 0 0
8 query elem.tabIndex uppercase when set as 0 in markup as uppercase 0 0 0 -1
9 query getAttribute(tabindex) lowercase when set as 0 in markup as lowercase 0 0 0 0
10 query getAttribute(tabIndex) uppercase when set as 0 in markup as lowercase 0 0 0 null
11 query getAttribute(tabindex) lowercase when set as 0 in markup as uppercase 0 0 0 null
12 query getAttribute(tabIndex) uppercase when set as 0 in markup as uppercase 0 0 0 0 1
13 query getAttribute(tabindex) lowercase when set via elem.tabindex lowercase 0 null null null
14 query getAttribute(tabIndex) uppercase when set via elem.tabindex lowercase 0 null null null
15 query getAttribute(tabindex) lowercase when set via elem.tabIndex uppercase 0 0 0 0
16 query getAttribute(tabIndex) uppercase when set via elem.tabIndex uppercase 0 0 0 null
17 query getAttribute(tabindex) lowercase when set via setAttribute as lowercase 0 2 0 0 0
18 query getAttribute(tabIndex) uppercase when set via setAttribute as lowercase 0 0 0 null
19 query getAttribute(tabindex) lowercase when set via setAttribute as uppercase 0 0 0 null
20 query getAttribute(tabIndex) uppercase when set via setAttribute as uppercase 0 0 0 0 3
21 query elem.tabIndex uppercase when it has not been set in markup 0 0 -1 -1
22 query getAttribute(tabIndex) upper or lowercase when it has not been set in markup 0 null null null
23 query elem.tabIndex from <a> with no explict value set 0 0 0 0
24 query getAttribute(tabIndex) upper or lowercase from <a> with no explict value set 0 null null null
25 query hasAttribute(tabindex) lowercase when set in markup as lowercase NA true true true
26 query hasAttribute(tabIndex) uppercase when set inmarkup as lowercase NA true true false
27 query hasAttribute(tabindex) lowercase when set in markup as uppercase NA true true false
28 query hasAttribute(tabIndex) uppercase when set in markup as uppercase NA true true true 1
29 query hasAttribute(tabindex) lowercase when set via elem.tabindex lowercase NA false false false
30 query hasAttribute(tabIndex) uppercase when set via elem.tabindex lowercase NA false false false
31 query hasAttribute(tabindex) lowercase when set via elem.tabIndex uppercase NA true true true
32 query hasAttribute(tabIndex) uppercase when set via elem.tabIndex uppercase NA true true false
33 query hasAttribute(tabindex) lowercase when set via setAttribute as lowercase NA true true true
34 query hasAttribute(tabIndex) uppercase when set via setAttribute as lowercase NA true true false
35 query hasAttribute(tabindex) lowercase when set via setAttribute as uppercase NA true true false
36 query hasAttribute(tabIndex) uppercase when set via setAttribute as uppercase NA true true true
37 query hasAttribute(tabIndex) upper or lowercase from <a> with no explict value set NA false false false

Table Notes:

  1. Setting in markup as uppercase tabIndex does not work in XHTML to allow focus to element.
  2. setAttribute(tabindex) lowercase does not work in IE to allow focus to element.
  3. setAttribute(tabIndex) uppercase does not work in XHTML to allow focus to element.

twitter 28 Jun 2009 05:00 am

Twitter Weekly Updates for 2009-06-28

  • Why won’t tweetsville display my timeline anymore? Rebooted iPhone, cleared cache - I can see messages and favorites but timeline is blank? #
  • Testing a tweet from tweetsville - timeline won’t display? Thus have been out of touch last few days #
  • working on adding aria-readonly to the dojox.DataGrid #dojo #ARIA #a11y #
  • Anyone know where pressing enter to submit a HTML form (that has submit btn) is defined? Can’t find in HTML spec but seems is std practice #

Powered by Twitter Tools.

Accessibility 23 Jun 2009 03:57 pm

Working with disabled (the attribute)

Once again I was bitten by the manner in which the difference browsers report the value of the disabled attribute. I decided to test the different ways of using the disabled attributes and record my results.

When writing JavaScript I generally use the object.getAttribute("attributeName") syntax to get an attribute value. However, this will return very inconsistent results for the disabled attribute. What makes it even worse, is there is more than one way to specify the disabled attribute on an input element. In HTML 4.01 you should just add the keyword disabled. In XHTML 1.1 you must use disabled="disabled". You can also use this in HTML 4.01.

What I learned from all of my testing is:

  • Use disabled (HTML 4.01 only) or disabled=”disabled” (HTML or XHTML) to set in markup.
  • When setting via scripting use one of the following to disable and enable, respectively
    • inputObj.disabled=true and inputObj.disabled=false via boolean values;
    • inputObj.disabled=”disabled” and inputObject.disabled=”" via string values;
    • inputObj.setAttribute(”disabled”, “disabled”) and inputObj.removeAttribute(”disabled”)
  • When testing for the disabled attribute on an input element, use inputObject.disabled for consistent results between browers.

Full testing results are tablulated at Testing the Disabled Attribute.

twitter 21 Jun 2009 05:00 am

Twitter Weekly Updates for 2009-06-21

  • can u believe that pressing shift+enter works differently in IE 8 if my Local intranet options are set to auto detect local intranet ntwrk? #
  • just finished presenting to 7th graders at local school - trying to interest them in engineering. Had them build bridges out of paper. Fun! #
  • some days fighting to maintain keyboard support feels like a losing battle. Now fighting with IE about how to check for tabindex. #a11y #
  • day off of work to visit elderly parents - although I think work would be easier :-) #
  • what’s up with Nambu thinking every tweet has replies???? #

Powered by Twitter Tools.

twitter 14 Jun 2009 05:00 am

Twitter Weekly Updates for 2009-06-14

  • OK so I should dig a bit further before jumping to conclusions - http://sphinx.pocoo.org/ can generate accessible HTML doc #
  • Maybe a better question to ask is, “what format should be used for creating accessible Web base help?” #
  • Any one know of resources comparing accessibility of CHM vs PDF formats? I need to get up to speed fast. Thx! #a11y #
  • Committed the ondijitclick event handler changes - FINALLY! see http://bugs.dojotoolkit.org/changeset/17832 #
  • FINALLY have rewrite of ondijitclick event handler complete Waiting for code review. Was in keyboard browser event hell for too long! #Dojo #

Powered by Twitter Tools.

twitter 07 Jun 2009 05:00 am

Twitter Weekly Updates for 2009-06-07

  • after all the a11y work I did on the DataGrid I get discouraged when people complain it isn’t accessible enough for their needs -sigh #dojo #

Powered by Twitter Tools.

twitter 31 May 2009 05:00 am

Twitter Weekly Updates for 2009-05-31

  • Not much tweeting lately. Struggling through keyboard event hell for unified handler for click, enter and space keys for dojo widgets #dojo #
  • how do I run safari 3 and safari 4 beta on same machine? I guess I could use web kit daily rather than safari 4 beta if I have to. #
  • Right NOW Attending ARIA Webinar via EASI http://easi.cc/entrance.htm #

Powered by Twitter Tools.

twitter 24 May 2009 05:00 am

Twitter Weekly Updates for 2009-05-24

  • RT @iStelios : Importance of HTML Headings for Accessibility - Raymond Selda Blog | http://tinyurl.com/qoght8 #a11y #
  • Speaker lineup for the Ajax Exp in Boston: 48 men 1 woman. Not enough women with important titles I guess - how sad. #
  • they are coming by to empty the office trash - must be time to go home! #
  • MacBook Pro screen went black, could see and move the mouse but typing any characters just beeped at me. Had to reboot! #
  • RT @kliehm (edited) WTF IE8 supports #ARIA, but many features only on Windows Vista+ http://is.gd/AJ5u http://is.gd/AJ5J #a11y good 2 know #

Powered by Twitter Tools.

twitter 17 May 2009 05:00 am

Twitter Weekly Updates for 2009-05-17

  • Got some embarrassingly stupid bugs fixed today. Had to admit my stupidity and lack of thorough testing. That’ll learn me! #dojo #
  • More info on IEEE Accessing the Future Conference July 20-21 in Boston http://tinyurl.com/qs3hnv Hoping I’ll be there ;-) #
  • Heading home from AccessU AUS to BOS #
  • embarrassed by bug in dojo changeset [17496] have fix but need to test more when back home before I commit Don’t want to break twice! #Dojo #
  • Arrived in Austin, TX for AccessU! #

Powered by Twitter Tools.

twitter 10 May 2009 05:00 am

Twitter Weekly Updates for 2009-05-10

  • worn out after visiting elder parents for the day. It is so hard to become the parent of your parents! #
  • Getting ready for AccessU in Austin, Tx next week. There is still time to register for GREAT a11y training - http://tinyurl.com/clha33 #
  • strange - col-resize and row-resize cursors are not visible in high contrast mode in Firefox when running in Parallels/WinXP on Mac?? #
  • Just found Mitch Kapor (mkapor) on twitter!As an old time Lotus employee (joined in January 1984) I had to follow! #
  • looking for keyboard accessible flash player that works in Firefox - any recommendations? #

Powered by Twitter Tools.

Next Page »