Tabs have proven to be a reliable and intuitive interface model for web pages that contain related content. But depending on how you set things up, tabs have one serious flaw: They frequently make it difficult or impossible to bookmark a specific tab. That is, if you have a page with five tabs on it, and I want to send someone to that page with specific tab showing, how do I do it?
We ran into this issue on a recent project. The client had two specific requirements for using a tabbed interface on some of their pages:
- The URL in the browser’s address bar must update when a tab is clicked, so that your normal web user would see that each tab has a unique URL.
- If someone sent that link around, the page would load with the correct tab content exposed, and move to the tabbed area, while leaving the tabs themselves visible so that a new visitor would understand that the were looking at only part of the page.
Working with the client’s implementation team, we had already decided to use jQuery for the site’s JavaScript, and further to use the jQuery UI scripts because they provide quite a bit of funcitonality that we wanted. Unfortunately, jQuery UI’s tab widget failed both of our requirements.
To be clear, if you use jQuery UI tabs, and someone figures out how to send around a tab-specific link, the page will load with the correct tab exposed. But it loads the page at the top of the tab content area instead of at the top of the tabs themselves. So someone who’s never visited the site before would have to scroll up to realize that there are other tabs that might contain content they’d also be interested in.
The bookmarking issue is one refered to directly on the jQuery UI pages. The script that was adapted for the tabs widget used a history plugin that needs some rewriting, and the jQuery UI team has not had time to update those scripts.
Fortunately, the jQuery scrollTo plugin and its related localScroll plugin solved both of our problems quite nicely. Those plugins provide some very slick functionality for sliding users around on web pages, but we’re going to use them in a much less flashy way.
Loading the Plugins
As with any jQuery plugin, you can keep the scripts in separate files and load them all as needed, or you can gang them up in one file. It depends whether your set up benefits from a slight larger file and fewer HTTP requests (if you’re using the plugins on all or most of your pages) or from having smaller, more discrete files.
Just make sure the plugins are loaded before or with your site’s JavaScript file.
Creating the Tabs
All of our calls happen within document.ready() function.
First we’ll create the tabs using the normal jQuery UI technique. In this case, we’ve wrapped the tabs ul and related divs in a div with a class of “tab-set”.
$(".tab-set").tabs();
Getting New Visitors to the Correct Tab
Next, we want to see if we need to load a specific tab. We’ll check to see if the page we’re on has a “tab-set” div, and check the URL to see if there’s a hash on the end of it. If yes to both, then we use the scrollTo plugin to jump us down to the “tab-set” div — which keeps the tabs visible — while relying jQuery UI’s default behavior to show the correct tab content.
if($(".tab-set") && document.location.hash){
$.scrollTo(".tab-set");
}Creating Bookmarkable URLs for the Tabs
Once a user is on the page, we use the localScroll plugin to update the URL in the address bar while keeping the page from reloading.
$(".tab-set ul").localScroll({
target:".tab-set",
duration:0,
hash:true
});What that says is “Scroll to the div ‘tab-set’ instead of the target of the link itself, do it with no animation, and add the hash to the URL”.
That’s it! All requirements met.
Demo Pages
Default jQuery UI Tabs
http://muledesign.com/demo/tabs/default-tabs.html
Be sure to click on the tabs and check your address window.
Then the same URL with a hash on it, which you would find if you understood right- or control-clicking, but the average web user might not:
http://muledesign.com/demo/tabs/default-tabs.html#comments
Bookmarkable jQuery UI Tabs with scrollTo and localScroll
http://muledesign.com/demo/tabs/bookmark-tabs.html
Again, be sure to click on the tabs and check your address window.
And then with the hash on it, which URL is available either with the right/control-click or by copying and pasting your address window.
http://muledesign.com/demo/tabs/bookmark-tabs.html#comments
Links
jQuery UI: http://jqueryui.com/
scrollTo Plugin: http://plugins.jquery.com/project/ScrollTo
localScroll Plugin: http://plugins.jquery.com/project/LocalScroll








9 comments so far. Add yours below.
Kit says:
Beautiful. One comment: it doesn't play well with browser history (at least not in FF3.0/OS X). When I get the chance, I might hack at this plugin and see if I can get that going.
May 15, 2009 2:57 PM
Jason Ronallo says:
Thank you. Great little tutorial that was exactly what I needed to allow linking directly into a tab.
May 27, 2009 6:55 AM
Kyle says:
Hi, the scrollTo functionality doesn't seem to have any effect on page position for IE, either 6, 7 or 8. any tips to get it working in IE?
June 2, 2009 7:36 AM
Kyle says:
Actually it doesnt seem to work in Opera or Safari either, just Firefox for me... it doesnt work for this demo page or for my own version of your code
June 2, 2009 7:43 AM
brian says:
nice job this is what i was looking for.
June 18, 2009 9:51 PM
shadow says:
Somehow jquery ui 1.7.2 is breaking the bookmarking part. It works fine without the ui but not with the ui script.
July 26, 2009 7:40 AM
Gabe says:
This is a great post, and it works well with one set of tabs on the page. I can't seem to figure out how to make it work with more than one sent of tabs, though. How would you get it to scroll to a specific tab set if there is more than one on the page?
August 17, 2009 12:37 PM
Kyle says:
Hi, is this working for everybody in any browser other than Firefox? i cant get it to function except in firefox. when i click on a link to arrive at a page it stays at the top for a second then goes down to the top of the tabs anyway...
any help much appreciated!
August 18, 2009 9:40 AM
Kyle says:
i found a way to make this work in most browsers. wrap the $.scrollTo function inside a setTimeout function, and it works fine (still placed within document ready function in page header). so for example,
$.scrollTo(0);
would become:
setTimeout("$.scrollTo(0)",100);
this works in IE 7/8, Navigator, Firefox, Safari, Chrome. In IE6 and Opera, the timeout would need to be bigger to make it work (e.g. 1000 or 2000) but personally i dont want to do that just for those browsers. i think it's because if the page hasnt fully loaded the scrollTo doesnt operate properly, however moving the .scrollTo function to the very bottom of the HTML code (just above doesnt work either.
anyway hope this helps people!
August 30, 2009 6:06 AM