Last year I came up with the original semantic tab box, now I’m improving it. Here are the things I wanted to fix:
- Keep JavaScript unobtrusive — no inline event handlers and needs to work without JavaScript.
- Create a standard API that can be easily reused and customized.
- Make the markup more flexible.
- Support both vertical and horizontal tabs.
- Don’t constrain the height of the box — let it expand to the size of the content.
- Keyboard navigation.
How is this better that other tab boxes out there?
All the tab boxes I’ve seen overcomplicate their solutions. They start with an unordered list of the tab names, followed by the content blocks. With a bit of CSS this looks very nice, but for screen readers the content is disconnected from the tab names and can be very confusing. Just try turning off CSS, you’ll see how horrible this looks:
The Internet is a worldwide, publicly accessible network of interconnected computer networks that transmit data by packet switching using the standard Internet Protocol (IP).
Accessibility is a general term used to describe the degree to which a system is usable by as many people as possible.
Progressive enhancement is a label for a particular strategy of Web design that emphasizes accessibility, semantic markup, and external stylesheet and scripting technologies…
Notice how the content is disconnected from the “tabs” when CSS is disabled (or when being read by a screen reader).
To solve this problem, most people just duplicate the tab name with a header (h2, h3, etc) at the top of each content block and use CSS to hide them from visual users. Here’s an example of what this solution looks like without CSS:
Internet
The Internet is a worldwide, publicly accessible network of interconnected computer networks that transmit data by packet switching using the standard Internet Protocol (IP).
Accessibility
Accessibility is a general term used to describe the degree to which a system is usable by as many people as possible.
Progressive Enhancement
Progressive enhancement is a label for a particular strategy of Web design that emphasizes accessibility, semantic markup, and external stylesheet and scripting technologies…
Sure this works, but why the redundancy? Yuck!
My solution gets rid of the unordered lists and formats the content blocks logically — with header tags.
Enough talk…
…lets get to the examples:
- Simple-Horizontal: A simple horizontally oriented tab box.
- Simple-Vertical: A simple vertically oriented tab box.
In <head>
<script type="text/javascript"> var tabs = new Tabbox("editorTabs") </script>
In <body>
<div id="myTabbox"> <!-- Internet Tab --> <div class="tabPanel selected"> <h3><a href="#interWebTab">Internet</a></h3> <div id="interWebTab" class="tabContent"> <p> The Internet is a worldwide... </p> </div> </div> <!-- Accessibility Tab --> <div class="tabPanel"> <h3><a href="#accessTab">Accessibility</a></h3> <div id="accessTab" class="tabContent"> <p> Accessibility is a general term used to... </p> </div> </div> </div>
Pretty simple huh?
Accessibility and Non-JavaScript Support
This new version supports accessibility by using CSS to hide the content divs (<div class="tabContent">) off screen, instead of with the unaccessible display:none CSS property.
These CSS classes are applied with JavaScript, so the content will be viewable if JavaScript is disabled or broken on the page. Try viewing the examples with JavaScript disabled and you’ll see what I mean.
API
To setup the tab box all you need to do is initialize the Tabbox object with the main div ID:
var box = new Tabbox("myTabbox", { header: "h3",
vertical : true,
select: 1,
autosize: true });
All the values in the second parameter are optional:
| Name | Default | Description |
|---|---|---|
| header | “h3″ | The header element used for each tab name. This element cannot be used anywhere else in the content block. |
| vertical | false | If the tabs should be oriented vertically. The tabs are setup horizontally by default. |
| select | 0 | The tab index to select initially. |
| autosize | true | Automatically size the box to the content of the tab. |
The code has been commented and layed out logically so updating it with features and enhancements should be easy. Speaking of enhancements…
Advanced Example — Hey Look! Something shiny.
So far the examples have been rather simple and plain so I wanted to create one that was more advanced. This example has a more complex UI, animations and implements the YUI history manager. Now when you change tabs it adds history to your browser and the back button will select the previous tab. Check it out — it’s the Über-Cool, Shiny, Tab Box.
Download
Now that you’ve seen the examples, you can download all the code and use it on your site:
tabbox2.zip (46K)
Add to: Del.icio.us | Digg it | Slashdot | Y! MyWeb

19 Responses
Matt Says:
August 3rd, 2007 at 8:05 am
Hi Jeremy,
Thanks so much for this, it is exactly what I was looking for. I’ve run into an issue, though…
I’ve placed an unordered list into the content area, and in Firefox (Windows), the entire list is not displayed (cuts off the bottom one or two links). A page refresh will bring it up. This happens more often that not, but not every time I load the tab.
I’ve validated all of the code, including the CSS. The page itself is valid XML, w/a DOCTYPE of XHTML 1.0/Strict.
Have you run into this, or do you have a suggestion as to what might be causing it? If it was a CSS bug, I’d expect it to show up in IE instead of Firefox, but the tabs work fine there.
Thanks for any help you can provide…
André Says:
August 9th, 2007 at 3:32 am
Hi Matt,
I used this exellent stuff, too, and I´m not experiencing this issue. Maybe you can post some code?
Kind regards
André
Matt Says:
August 10th, 2007 at 1:17 pm
A visual example is here: http://www.utmb.edu/memos/tab-an1.gif
Matt Says:
August 10th, 2007 at 7:17 pm
I submitted some code, André, but it didn’t make it past the filter. I can email it if you are that interested. It’s pretty much an out-of-the-box implementation, as I was testing it out. I only changed colors and BG graphics.
tom van wynen Says:
April 2nd, 2008 at 7:51 am
I downloaded the zip file but it seems to be corrupted (using win xp here).
love the examples and the graceful degradation; will be using it for tabbed content on the site above, where I have large amounts of multilingual content coming in via an internal xml feed, need a tabbed interface to present the language options.
MJ Says:
May 14th, 2008 at 4:52 am
Hi,
The content in your examples directory appears to be 404. Was this intentional, or will they be available again at some point in the future? I’m interested in your tabbox2 code.
prolan1 Says:
August 5th, 2008 at 5:15 am
gl0REP qazwsx
prolan3 Says:
August 5th, 2008 at 5:30 am
zDGYI8 wwwwqqqqsssddd
prolan5 Says:
August 5th, 2008 at 5:44 am
LDRShz eeeerrrffddgggggggccccc
derf Says:
August 15th, 2008 at 1:01 am
A6xder re re rerrrreeee gththtt
Blacki Says:
September 3rd, 2008 at 7:32 pm
I downloaded the zip file but it seems to be corrupted (using win xp here).
I love the examples and the graceful degradation; will be using it for tabbed content on my site.
Mats Lindh Says:
October 6th, 2008 at 12:27 pm
So, what license have you published this under? It is also free for commercial use?
Jeremy Gillick Says:
January 5th, 2009 at 6:16 pm
@Mats
Yes this code is totally open, unlicensed, and can be used for any purpose.
Tim Says:
March 27th, 2009 at 8:34 am
Thanks Jeremy… well done.
Is it possible to implement multiple instances of this on a single page? I’ve tried but only the top one works.
Kate Says:
August 8th, 2009 at 12:29 am
Hi - nice work love it - just a quick one from a javascript beginner on the super shiny example if i center the tabbed content on the page the animated selector arrow is thrown off tilt any idea how i can fix this?
Thanks
Emre Says:
November 30th, 2009 at 6:58 pm
Thanks Jeremmy, this is excellent! I’m using it in a few pages, and it works really fine.
I have a question though. Is it possible to close the open tab when it’s header is clicked (without selecting another tab)?
Jigz Says:
May 4th, 2010 at 12:34 am
Great work Jeremy!
@Tim I was facing the same issue. Just put “this.tabs = [];” after “formatTabbox : function(){” [Line 89 for me] and you’l be good to go.
Greg Harris Says:
May 21st, 2010 at 8:16 pm
Awesome, blog post!!
jamie Says:
August 16th, 2010 at 6:43 am
this is beautiful, exactly what i was looking for. i dont work with the javascript side but will be passing this solution on to those who do