Create a Graceful jQuery Tabbed Widget in 5 Easy Steps

Tabbed widget boxes have become a popular way to display useful information while conserving valuable screen real estate. Here you’ll learn how to use jQuery and some CSS to create an attractive tabbed widget that gracefully degrades into separate boxes. Come check it out!

New to jQuery? Check out the jQuery tutorials in Webitect’s tutorial channel.

The great beauty of the jQuery library lies in its effortless selection and manipulation structure, which makes rearranging static elements into dynamic organizations tons easier. Today, I’ll show you how use these abilities to build one of those popular tabbed widgets for displaying blog info (recent posts, popular posts, etc.). Of course, for this application we could use jQuery UI’s tabs feature, but we’re doing it by hand today for two reasons:

  1. For this small feature, we don’t need all the extra file size of jQuery UI. All we need is basic jQuery and a few lines of our own code, which is much more efficient.
  2. We don’t want to get locked into using pre-made functions all the time. While this isn’t truly ‘under-the-hood’, it will help us keep our code minds sharp and innovative, and, as I’ll show later, this concept can be applied in other situations, not just for tabbed widgets.

Ready? Let’s get started!

Demo

Want to see a working demo? Click here.

Step 1: Build the Infrastructure

The first thing we have to do is set up our blank page- index.html. We want it to look perfectly acceptable without any JavaScript, so we’ll create 3 separate widgets, each with an h5 title and unordered list inside. In the example, these are going to hold lists of the most popular posts, the recent posts, and the blog’s categories. Here’s the code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
	<script type="text/javascript" src="tabbedwidget.js"></script>
	<link type="text/css" href="style.css" rel="stylesheet"/>
</head>

<body>
	<div id='sidebar'>
		<div class='widget'>
			<h5>Popular</h5>
			<ul id='popular'>
				<li><a href='#'>Pink Fizz Storms Market</a></li>
				<li><a href='#'>Studio Hires Elephant</a></li>
				<li><a href='#'>Installing PS3</a></li>
				<li><a href='#'>How to Destroy Your Computer</a></li>
				<li><a href='#'>Alphabet Soup</a></li>
			</ul>
		</div>
		<div class='widget'>
			<h5>Recent</h5>
			<ul id='recent'>
				<li><a href='#'>How to Eat a Live Frog</a></li>
				<li><a href='#'>Everybody Else Was Doing It</a></li>
				<li><a href='#'>10 Ways to Anger Your Freelancer</a></li>
			</ul>
		</div>
		<div class='widget'>
			<h5>Categories</h5>
			<ul id='categories'>
				<li><a href='#'>Resources</a></li>
				<li><a href='#'>Tutorials</a></li>
				<li><a href='#'>Interviews</a></li>
				<li><a href='#'>Showcases</a></li>
			</ul>
		</div>
	</div>
</body>
</html>

NOTE: I’ve used static lists because this is an example. Of course in real life you would use server-side scripting to generate these lists. In WordPress these would be <?php get_mostpopular(); ?> (assuming you have Hector Cabrera’s Popular Posts Plugin), <?php wp_get_archives(‘type=postbypost&limit=3′); ?>, and <?php wp_list_cats(); ?>

Step 2: Make it Pretty

It doesn’t have to be spectacular, but it’ll be a lot more fun, and practical, to give our widgets some nice styles. Of course, you’ll want to apply your own styles that match the overall theme of the site, but this is a nice default to get you started:

body{
	background-color: #E5DFCE;
	text-align: center;
}

#sidebar{
	margin: 100px auto;
	width: 300px;
	text-align: left;
}

.widget{
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-top: 1px solid #FFFFFF;
	border-left: 1px solid #FFFFFF;
	border-bottom: 1px solid #DDDDDD;
	border-right: 1px solid #DDDDDD;
	background-color: #EEEEEE;
	font: 11pt Georgia,Times,serif;
	color: #999;
	padding: 7px;
	margin: 20px;
	width: 300px;
}

	.widget ul{
		list-style-position: inside;
	}
h5{
	font-size: 14pt;
	margin: 5px;
}
a{
	color: #7B0909;
	font-family: Helvetica;
}

Step 3: Stack it Up!

Alright, here comes the fun part- using jQuery’s awesome capabilities to rearrange our widgets. We’re going to hide the widgets, then take their content and place it inside a newly created tabbed container. In the demo, I’ve put my js code in a separate file- tabbedwidget.js. If you are unfamiliar with jQuery, now would be a good time to check out the Official jQuery API Reference and browse a bit to get familiar with it (in this tutorial I’m assuming you have a basic knowledge of jQuery functions and selectors). You also might be interested in reading Smashing Magazine’s article on the finer details of module tabs- Module Tabs in Web Design- Best Practices and Solutions.

Anyways, the first thing we’re going to do is set up our $(document).ready() function.

$(document).ready(function(){

});

Next, we’ll hide all the widget wrapper divs, specified in my demo with a class of “widget”.

$(document).ready(function(){
	$(".widget").hide();
});

Now, we’ll use the first widget as a reference point to insert our tabbed container, using the jQuery before() function. This tabbed container (a div) is going to hold a wrapper (a ul) for the tabs and a wrapper (another div) for the content area. In order to make our code more readable, we’ll go back to the beginning of our function and define a variable, “newWidget”, to hold the HTML for the new container. This is what we have so far:

$(document).ready(function(){
	var newWidget="<div class='widget-wrapper'>
	<ul class='tab-wrapper'></ul>
	<div class='new-widget'></div></div>";
	$(".widget").hide();
	$(".widget:first").before(newWidget);
});

So we have a new container, with no tabs or content in it. To add content and corresponding tabs, we’ll use the each() function to grab each unordered list inside a div with a class of ‘widget’. Then for each of these, we’ll add a tab to the tabwrapper, using the ul’s id as a title. Then we take the actual ul and append it to our new widget, making sure to close our each() function.

	$(".widget > ul").each(function(){
		$(".tab-wrapper").append("<li class='tab'>"+this.id+"</li>");
		$(this).appendTo(".new-widget");
	});

Step 4: Create the Tabs

We now have a widget with tabs and content- but the tabs don’t do anything. That’s our next step. We’ll use click() to trigger a callback function which does three things:

  1. First it hides all unordered lists inside the new widget.
  2. Then, since we know the tab text matches the id of the corresponding ul (remember the ul id was used as the text), we’ll add a hash in front of the text and call show()
  3. Third, we remove the class “active-tab” from all tabs, and add it again to the target tab.

The code looks like this:

	$(".tab").click(function(){
		$(".new-widget > ul").hide();
		$('#'+$(this).text()).show();
		$(".tab").removeClass("active-tab");
		$(this).addClass("active-tab");
	});

The last thing to do is initialize by triggering “click()” on the first tab. That way, when the page loads one tab will already be selected. Here’s our final js file:

$(document).ready(function(){
	var newWidget="<div class='widget-wrapper'>
		<ul class='tab-wrapper'></ul>
		<div class='new-widget'></div></div>";
	$(".widget").hide();
	$(".widget:first").before(newWidget);
	$(".widget > ul").each(function(){
		$(".tab-wrapper").append("<li class='tab'>"+this.id+"</li>");
		$(this).appendTo(".new-widget");
	});
	$(".tab").click(function(){
		$(".new-widget > ul").hide();
		$('#'+$(this).text()).show();
		$(".tab").removeClass("active-tab");
		$(this).addClass("active-tab");
	});
	$(".tab:first").click();
});

Ok, you now have a working tabbed widget. It’s time to go back to style.css and add some styles to make our tabs look pretty. This would be a great start:

.new-widget{
	margin: 0px;
	-moz-border-radius: 10px;
	-webkit-border-radius: 10px;
	border-top: 1px solid #FFFFFF;
	border-left: 1px solid #FFFFFF;
	border-bottom: 1px solid #DDDDDD;
	border-right: 1px solid #DDDDDD;
	background-color: #EEEEEE;
	padding: 7px;
	width: 300px;
	clear: both;
}
	.new-widget ul{
		display: none;
	}

.tab-wrapper{
	width: 285px;
	margin: 0px 7px;
}
	.tab-wrapper ul{
		margin: 0px;
	}
.tab{
	width: 90px;
	height: 33px;
	float: left;
	background: url(tab.png) no-repeat bottom center;
	text-transform: capitalize;
	color: #BBB;
	text-align: center;
	line-height: 2.5em;
	cursor: pointer;
	list-style: none!important
}

.active-tab{
	background: url(active-tab.png) no-repeat bottom center;
}

And here, (drumroll please) is the finished version, with and without JavaScript:

With without Javascript

Step 5: Go Have Some Pretzels

That’s it! Quick, easy and entirely accessible. You now have 100% accessible widgets, well arranged for SEO and quite handsome without any JavaScript. And, for those folks who do have JS capabilities, our widgets are packed into an efficient, screen saving container, using only 16 lines of code.

There are plenty more opportunities for this as well. You could take items out of the sidebar and put them in a dropdown menu at the top of your page. You could take blog posts and put them in a rotating featured posts section. You could build a jQuery plugin even more powerful than tabs() that could grab content and repackage it using any number of parameters. The possibilities are endless!

So tell me- do you have questions about the tutorial? Ideas for further development of this concept? Suggestions for improvement on the current model? I’d love to hear your thoughts!

Written By Nick Parsons

Nick is the editor of Webitect and a developer + designer from Houston TX.

11 Comments

  1. Dzinepress

    September 2nd, 2009 at 01:20 am

    really helping stuff you sharing. thanks

  2. Taimur

    September 2nd, 2009 at 11:19 am

    Thanks Man … This was so helpful :)

  3. 9swords

    September 4th, 2009 at 02:13 am

    Very graceful degradation! Look’s great :)

  4. David

    October 20th, 2009 at 09:25 pm

    I like Pretzels:) Nice tutorial.

  5. Bolly

    February 27th, 2010 at 12:21 am

    nice gud

  6. Tung

    September 8th, 2010 at 03:37 am

    Very cool

  7. Gautam Doddamani

    July 4th, 2011 at 08:50 am

    the demo link is not working! :(

  8. Ash Robbins

    October 31st, 2011 at 08:27 am

    I’m a bit late to the party, but just wanted to say thanks for this, it works a treat!

    P.S. As Gautam says above, the demo link is broken.

  9. Andrew

    December 3rd, 2011 at 03:28 pm

    Great widget – do you have any ideas on how to make the tabs rotate from one tab to the next, say every 20 seconds. And then if user want to click a tab, the rotation stops for a while? I have been looking for this feature and haven’t been able to find anything. Thank you for any suggestions.

  10. Caroline | Makeupedia.se

    February 7th, 2012 at 02:28 pm

    I use self-hosted wordpress, is it the second or/and the first code in Step 4 I should insert in my functions.php?

    Thanks in advance!

  11. qw

    May 8th, 2014 at 12:48 am

    asdas

What Do You Think?