Search code examples
htmltabindex

How can I implement a skip navigation link, when the page content isn't contained and has explicit tabindex?


I have a layout which contains a header and navigation bar, followed by the page content, and finally a footer.

The page content is not contained in any container, but is instead siblings of the header, footer, and navigation bar. I cannot wrap the page content in a div.

I have a skip navigation link, which is contained in the header and is supposed to bring focus below the navigation bar, to the page content. Because the page content isn't contained, there is an empty div below the navigation bar, which I use as an anchor.

This approach works fine with page content using default tab order, but if the page content has tabindex attributes set, hitting tab after using the skip navigation link won't follow the desired tab order.

Is there any way for me to implement a skip navigation link correctly, given that I can't wrap the content in a div, and I don't know whether or not the content has non-default tab order?

See the snippet below; if you tab to 'Skip Navigation' and hit enter, the next tab press will bring you to the last element in the desired tabbing order.

<!-- Header -->
<div style="height: 40px; background-color: rgb(120, 0, 120);">
    <a href="#" tabindex="1">Foo</a>
    <a href="#" tabindex="2">Bar</a>
</div>
<a href="#content" tabindex="3">
	<span>Skip Navigation</span>
</a>

<!-- Navigation Bar -->
<div style="height: 30px; background-color: rgb(190, 190, 30);">
    <input tabindex="4" />
</div>

<div id="content" tabindex="-1"></div>

<!-- Content -->
<div style="height: 80px; background-color: rgb(30, 190, 190);">
    <input tabindex="7" />
    <input tabindex="5" />
    <input tabindex="6" />
</div>


Solution

  • Maybe, a little bit of js is an option for you?

    <a href="#content" tabindex="3"
       onfocus="focus_navigation()"
       onclick="skip_navigation(5)">
        <!-- 5 as next required tabindex after skipping -->
        <span>Skip Navigation</span>
    </a>
    <div id="content" tabindex="-1"></div>
    
    <script>
      function skip_navigation(index) {
        var c = document.querySelector('#content')
        c.tabIndex=index;
        setTimeout(c.focus.bind(c), 100)
      }
      function focus_navigation() {
        document.querySelector('#content').tabIndex=-1
      }
    </script>
    

    As you can see, skip_navigation is run upon click, which sets next needed tabindex to content and focuses it.