jQuery Tabbed Interface / Tabbed Structure Menu Tutorial

Written by Kevin Liew on 19 Mar 2009
719,956 Views • Tutorials

Introduction

Nowadays, a lot of websites are using tab based content as a way to save spaces in a webpage. I have seen a lot of wordpress websites using a tabbed interface for its category, posts, comments and random posts content. It's a good "space-saver" and if used it correctly, it can boost your website usability as well. Right, first of all, we need to have the ideas and the design structure for this tabbed interface.

Before we start, if you are looking for a web hosting company, this is a good review - Hostgator Review.

My ideas:
  • Buttons on the top, content reside in different DIV elements,
  • Click on one of the buttons, it shows the relevant content;
  • Click on other buttons, it hides the existing and display the correct one.

The Design structure:

tab menu structure diagram

* Thanks to WeFunction.com for the amazing icons

Advertisement

2. HTML

In case the image above doesnt load, allow me to explain the design structure again. The UL#tabMenu is the buttons on the top a.k.a. Tabs. This is where you click, and it will trigger the jQuery to loads the content.

Inside the boxBody, you need to specify 5 DIVs, the number of DIV will depend on how many items you defined in #tabMenu, in this case, we have 5, therefre, you need 5 DIV elements defined in .boxBody.

The javascript loads the content based on the DIV's index in .boxBody. For example, if you clicked o the first button (the star or index 0), it will load the first DIV in the .boxBody (DIV index 0).

Therefore, arrangement of DIV in .boxBody must match with the arrangement of button in #tabMenu.

<div class="box">

  <ul id="tabMenu">
    <li class="posts selected"></li> <!-- default button-->
    <li class="comments"></li>
    <li class="category"></li>
    <li class="famous"></li>
    <li class="random"></li>
  </ul>

  <div class="boxTop"></div>

  <div class="boxBody">
  	<!-- default page-->
    <div id="posts" class="show parent">
      <ul>
        <li>Post 1</li>
        <li>Post 2</li>
        <li class="last">Post 3</li>
      </ul>  
    </div>  
  
    <div id="comments" class="parent">
      <ul>
        <li>Comment 1</li>
        <li>Comment 2</li>
        <li class="last">Comment 3</li>
      </ul>
    </div>
  
 	<div id="category" class="parent">
   	  <ul>
   	    <li>Category 1</li>
   	    <li>Category 2</li>
		<li class="last">Category 3</li>
   	  </ul>  
   	</div>
  
  	<div id="famous" class="parent">
      <ul>
        <li>Famous post 1</li>
    	<li>Famous post 2</li>
    	<li class="last">Famous post 3</li>
	  </ul>  
    </div>
  
	<div id="random" class="parent">
	  <ul>
        <li>Random post 1</li>
	    <li>Random post 2</li>
    	<li class="last">Random post 3</li>
   	  </ul>    
	</div>        

  </div>

  <div class="boxBottom"></div>

</div>

3. CSS

You can always modify it to match your website. I will attach the psd file for this tutorial in the download and edit the css carefully. : ). Any suggestions please comment.

<style>

a {
	color:#ccc;
	text-decoration:none;
}

a:hover {
	color:#ccc;
	text-decoration:none
}

#tabMenu {
	margin:0;
	padding:0 0 0 15px;
	list-style:none;
}

#tabMenu li {
	float:left;
	height:32px;
	width:39px;
	cursor:pointer;
	cursor:hand
}

/* this is the button images */
li.comments {background:url(images/tabComment.gif) no-repeat 0 -32px;}
li.posts {background:url(images/tabStar.gif) no-repeat 0 -32px;}
li.category {background:url(images/tabFolder.gif) no-repeat 0 -32px;}
li.famous {background:url(images/tabHeart.gif) no-repeat 0 -32px;}
li.random {background:url(images/tabRandom.gif) no-repeat 0 -32px;}

li.mouseover {background-position:0 0;}
li.mouseout {background-position:0 -32px;}
li.selected {background-position:0 0;}

.box {
	width:227px
}

.boxTop {
	background:url(images/boxTop.gif)no-repeat;
	height:11px;
	clear:both
}

.boxBody {
	background-color:#282828;
}

.boxBottom {
	background:url(images/boxBottom.gif) no-repeat;
	height:11px;
}

.boxBody div.parent {
	display:none;
}

.boxBody div.show {
	display:block;
}


.boxBody #category a {
	display:block
}

/* styling for the content*/
.boxBody div ul {
	margin:0 10px 0 25px;
	padding:0;
	width:190px;
	list-style-image:url(images/arrow.gif)
}

.boxBody div li {
	border-bottom:1px dotted #8e8e8e; 
	padding:4px 0;
	cursor:hand;
	cursor:pointer
}

.boxBody div ul li.last {
	border-bottom:none
}

.boxBody div li span {
	font-size:8px;
	font-style:italic; 
	color:#888;
}

/* IE Hacks */
*html .boxTop {margin-bottom:-2px;}
*html .boxBody div ul {margin-left:10px;padding-left:15px;}

</style>

 

4. Javascript

Alright, the fun part. It took me a while to read the jQuery documentation to make it works the way I want. And yes, I made it. As usual, I have put comments on each line. I put the animate effect on category page. I have a tutorial about it - Navigation List menu + Jquery Animate Effect Tutorial

$(document).ready(function() {	

  //Get all the LI from the #tabMenu UL
  $('#tabMenu li').click(function(){
    
    //perform the actions when it's not selected
    if (!$(this).hasClass('selected')) {    
           
	    //remove the selected class from all LI    
	    $('#tabMenu li').removeClass('selected');
	    
	    //Reassign the LI
	    $(this).addClass('selected');
	    
	    //Hide all the DIV in .boxBody
	    $('.boxBody div.parent').slideUp('1500');
	    
	    //Look for the right DIV in boxBody according to the Navigation UL index, therefore, the arrangement is very important.
	    $('.boxBody div.parent:eq(' + $('#tabMenu > li').index(this) + ')').slideDown('1500');
	    
	 }
  }).mouseover(function() {

    //Add and remove class, Personally I dont think this is the right way to do it, 
    //if you have better ideas to toggle it, please comment    
    $(this).addClass('mouseover');
    $(this).removeClass('mouseout');   
    
  }).mouseout(function() { 
    
    //Add and remove class
    $(this).addClass('mouseout');
    $(this).removeClass('mouseover');    
    
  });

  
  //Mouseover with animate Effect for Category menu list  :)
  $('.boxBody #category li').mouseover(function() {

    //Change background color and animate the padding
    $(this).css('backgroundColor','#888');
    $(this).children().animate({paddingLeft:"20px"}, {queue:false, duration:300});
  }).mouseout(function() {
    
    //Change background color and animate the padding
    $(this).css('backgroundColor','');
    $(this).children().animate({paddingLeft:"0"}, {queue:false, duration:300});
  });  
	
  //Mouseover effect for Posts, Comments, Famous Posts and Random Posts menu list.
  $('.boxBody li').click(function(){
    window.location = $(this).find("a").attr("href");
  }).mouseover(function() {
    $(this).css('backgroundColor','#888');
  }).mouseout(function() {
    $(this).css('backgroundColor','');
  });  	
	
});

5. Finally

You will get a beautiful jQuery Tabbed Side Menu!

However, in category page, if you were using IE, the LI can't be hightlighted when mouse hover it in (that's why we all hate IE). If you know what's the problem, please advise : )

Last but not least, check out the demo or download the source code to play with it. Any questions. please leave your comment :)

Support me by bookmark this article and share it to your friends : ) Thanks

Update

15-9-2011: Fixed DIV issue.

14-4-2009: Remove click event in the LI, change the display attribute in #category to block.

Demo Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

183 comments
kevin Admin 15 years ago
@BoyKat: What you need to do is, remove this line in the click section:

window.location = $(this).find("a").attr("href");

and add this to the css:

#category a {display:block}

to achieve the same effect but without executing the hyperlink twice.

Cheers
Reply
Branden Silva 15 years ago
I like it. I definitely plan on using it but it's a bit buggy in IE7. I haven't tested it in IE6/8 yet.

This has been mentioned but just a screenshot to sum it up.

http://www.twitpic.com/31og6

Fix these and it will be that much better :)
Reply
kevin Admin 15 years ago
@Branden: I know what you meant, if you look at the one I used in this website, I have fixed that issue. I think I only tested it in ie6. You have to set the margin of the boxTop to negative value.

I'm on vacation at the moment, if you don't mind, check out the style_ie in this website. Cheers.
Reply
BoyKat 15 years ago
it seems this works:
a href="http://www.queness.com " target="main">Queness

but with the li in the front of the page it seems to want to open in both the menu and the main. and I have to remove the li in the front of the line to make it work but with that removed it will not animate. If you can please help I would be so greatfull
Reply
Cody R 15 years ago
I'm trying to make the link go to a new window (http://www.example.com/" target="_blank">example) and it works when I click on it, but it also takes me away from the page I'm on.

It loads two of the link, one in a new page like I want, and one on the page I clicked it on(do not want) is there a way around this, or am I just being dumb?
Reply
Branden Silva 15 years ago
That screen shot was taken in IE7 so I'm wondering why it's not taking the negative margin values. The tab separated from the body is still visible to me but I'll have to tweak around with it later.

Thanks anyways. It's funny how you dropped this exactly when I need it on a project. Seems to always work out that way when I'm not even looking.

Enjoy your vacation.
Reply
kevin Admin 15 years ago
@Branden: i think I put a condition to check for ie6, but not ie7 and above. I hope you have solved your this problem. Cheers

@Cody R: hi cody, I know the solution, what you need to do is refer to the comment above your comment. Remove the jquery code and change the css.
Reply
Pradeep CD 15 years ago
Awesome design...

I will use this sometimes...

thanks...
Reply
kevin Admin 15 years ago
@Beersage: hi.. yea, sorry for the hassle, but u have to escape the html tag in the comment. Back to the question, yes, u can separate it into different file... i'm using external js for this website too.
Reply
Beersage 15 years ago
Works great, thank you!

Just wondering if it is possible to use the javascript outline above in its own js file and call it from the header instead of putting all of the code there?

For example, instead of:




{skript type="text/javascript" src="js/jquery-1.3.1.min.js"}{/skript}
{skript type="text/javascript"}code{/skript}

How about...

{skript type="text/javascript" src="js/jquery-1.3.1.min.js"}{/skript}
{skript type="text/javascript" src="js/tabmenu.js"}{/skript}




The latter doesnt work.
Reply
Jason 15 years ago
Great code :-) ... is there any way to also make the tabs collapse when clicked again???
Reply
kevin Admin 15 years ago
@Jason: you need to remove this line and its bracket:

if (!$(this).hasClass('selected')) {
......
}

interestingly, if u read the first comment, phil actually recommended to disable the click if selected. : )
Reply
lawmacs 15 years ago
Thanks alot looking for this for a long time great stuff
Reply