Blog-Archiv

Samstag, 16. Januar 2016

HTML Input Focus Tab Order

Wherever you mouse-click on a web-page, or finger-tap, the input-focus will be set to that location. In case a focusable field is at that location, you actually can interact with the page then. But keyboard-navigating to such a field on a desktop computer mostly is an uncertain adventure.

By default, only focusable elements are reachable by keyboard. These are just

  • <a>
  • <input>
  • <select>
  • <textarea>
  • <button>

But you can make any element focusable by setting a tabindex attribute to it.

  • tabindex = "-1" will make the element focusable by mouse, or by a JS element.focus() call, but it won't be reachable by keyboard

  • tabindex = "0", the default for any focusable element without tabindex, will make the element reachable also by keyboard, but the tabbing order will be that of the HTML elements

  • tabindex = "1" or bigger will make the element focusable, and the tabbing order will be that of the tabindex values, from smallest to biggest; further these elements will be focused before those with tabindex = "0"

It is a little difficult to demonstrate tabindex on this Blog page, because here are a lot of links that request focus when tabbing through. Thus you should watch this here on my homepage.

But if your browser supports iframes, you may see the test view below. The iframe serves as local tabbing range. The tabindex values are rendered in red text to the right of the field. Focused fields will have a red border. First click this

button. When you press "Tab" after, the focus will move to the iframe. Then continue with the "Tab" key, and watch which elements are focused, and in which order. Finally the focus will go out of the iframe and continue with some Blog links. Mind that the button "Five" never will receive the focus, although it is a focusable element, but it has an explicit tabindex = "-1".

The tabbing rules are:

  1. start with the element having the lowest tabindex, starting from 1
  2. continue with next higher tabindex, ignoring gaps
  3. when having same tabindex, the HTML-order decides which is next
  4. when no more positive tabindex numbers are left, go to first in element-order with tabindex="0", whereby focusable elements without tabindex automatically have tabindex="0"
  5. do all tabindex="0" elements in their HTML-order

The focus will never go to an element having tabindex="-1" while using the keyboard. Nevertheless, when you mouse-click on it, it will have the focus. In case it does not have a tabindex at all, it can be focused only when it is a focusable element (see above).

As identical tabindex values will not be ignored, you can build tabbing groups by using the same tabindex for several related elements. But mind that then the HTML order counts. For example, you could have 3 elements using tabindex = "1", then 5 using tabindex = "2", and so on.

My browser, after having finished this traversal, goes to the "page-identity" toolbar button, then to the URL address line, then to the search-field, then back to the client-area, then starts again with tabindex elements.


Here is the source code of the test page. Copy & paste it into a .html file and try it out using a file:/// URL.

The tabindex attribute has been made visible by an ::after pseudo-element. There you can fetch attribute values in the content property by using the CSS function attr().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>Trace Input Focus</title>
    
    <style type="text/css">
      *:focus {
        border: 2px solid red;
      }
      *::after {
        content: attr(tabindex);
        padding-left: 1em;
        color: Tomato;
      }
    </style>
    
  </head>
  
  <body>
      
    <div>
      <div tabindex="0">One</div>
      <div tabindex="2">Two</div>
      <div tabindex="1">Three</div>
    </div>

    <div>
      <button>Four</button> <br>
      <button tabindex="-1">Five</button> <br>
      <button tabindex="3">Six</button> <br>
      <button tabindex="0">Seven</button>
    </div>

    <div>
      <p tabindex="8">Eight</p>
      <p tabindex="9">Nine</p>
      <p tabindex="8">Ten</p>
    </div>
  
  </body>

</html>

You can find further background information here.




Keine Kommentare: