Remy Sharp picks that old chestnut – tabs – and roasts it afresh on the open fire of JavaScript to see how a fully navigable, accessible and clickable set of tabs can work. Everybody knows some scripting and some CSS can help to make your website bright. Although it’s been said many times, many ways, please be careful to do it right.
REQUIREMENTS: WHAT MAKES THE PERFECT TAB?
All content is navigable and available without JavaScript (crawler-compatible and low JS-compatible).
ARIA roles.
The tabs are anchor links that:
Since tabs are clickable, the user can open in a new tab/window and the page correctly loads with the correct tab open.
Right-clicking (and Shift-clicking) doesn’t cause the tab to be selected.
Native browser Back/Forward button correctly changes the state of the selected tab (think about it working exactly as if there were no JavaScript in place).
are clickable
have block layout
have their href pointing to the id of the panel element
use the correct cursor (i.e. cursor: pointer).
The first three points are all to do with the semantics of the markup and how the markup has been styled. I think it’s easy to do a good job by thinking of tabs as links, and not as some part of an application. Links are navigable, and they should work the same way other links on the page work.
The last three points are JavaScript problems. Let’s investigate that.
...
THE SHITMUS TEST
Like a litmus test, here’s a couple of quick ways you can tell if a tabbing system is poorly implemented:
Change tab, then use the Back button (or keyboard shortcut) and it breaks
The tab isn’t a link, so you can’t open it in a new tab
These two basic things are, to me, the bare minimum that a tabbing system should have.
...
URI FRAGMENT, ABSOLUTE URL OR QUERY STRING?
A URI fragment (AKA the # hash bit) would be using mysite.com/config#content to show the content panel. A fully addressable URL would be mysite.com/config/content. Using a query string (by way of filtering the page): mysite.com/config?tab=content.
This decision really depends on the context of your tabbing system. FOr something like GitHub’s tabs to view a pull request, it makes sense that the full URL changes.
...
URL-DRIVEN TABBING SYSTEMS
Instead of making the code responsive to the user’s input, we’re going to exclusively use the browser URL and the hashchangeevent on the window to drive this tabbing system. This way we get Back button support for free.
With that in mind, let’s start building up our code. I’ll assume we have the jQuery library, but I’ve also provided the full code working without a library (vanilla, if you will), but it depends on relatively new (polyfillable) tech like classList and dataset (which generally have IE10 and all other browser support).

















