Search code examples
jqueryhtmlcsstabindex

HTML tabindex on <a> with children


I have a toggling navigation menu structured the following way:

<li>
  <a href="mylink.page">
    <span class="text">Link Text</span>
    <span tabindex="0" class="button"></span>
  </a>
  <ul>... children ... </ul>
</li>

span.text houses the link text and span.button is the element that a user can click or keypress enter to toggle the nested ul.

While tabbing through the menu (testing accessibility), my browser (tried in both latest public versions of Chrome and Firefox on Windows) focuses on the container a, then focuses on span.text, then finally on span.button. This is the behavior I want but don't want the container 'a' to get focused on - just go straight to span.text.

Note: When focused on container 'a', hitting enter does not activate the link, only the children spans activate the link when focused upon (I have prevented the link from working when keypress enter on span.button so the toggling works on keypress enter).

This behavior is fine and is essentially how I want it (spans being the links activated by keypress enter) expect I want to skip the container 'a' when tabbing and go straight to the children spans.

tabindex="-1" right? Nope. When adding tabindex="-1" to the container 'a', span.text no longer gets focused and an active link is gone. The browser focuses on the container 'a' and then skips over span.text to span.button. This is odd (at least to me). In my mind, tabindex="-1" is used for skipping the element while tabbing.

Any ideas how I can use tabindex on a combination of the container 'a' and the children spans to achieve what I stated above (tabbing through menu only hits span.name [which has active link] and span.button)? Or even a javascript/jquery solution?

Note: Having tabindex="0" seems to be the only way to tab to span.button.

EDIT: After tinkering for a bit, I put tabindex="0" on the container 'a' and it works beautifully in Chrome. Firefox still focuses on the container 'a'.


Solution

  • In jQuery, try:

    $('a:has(span[tabindex])').on('focus', function () {
        $(this).find('span[tabindex]').focus();
    }).on('keypress', 'span[tabindex]', function (e) {
        if(e.which === 13) { 
           this.click(); //this not $(this), to call native click method
           //or: $(this).parent()[0].click();
        }
    });
    

    For jQuery below 1.7, try:

    $('a:has(span[tabindex])').bind('focus', function () {
        $(this).find('span[tabindex]')[0].focus(); // call js focus(), not jq
    }).delegate('span[tabindex]', 'keypress', function (e) {
        if (e.which === 13) {
            this.click(); //this not $(this), to call native click method
            //or: $(this).parent()[0].click();
        }
    });