Tutorials

jQuery Tabbed Interface / Tabbed Structure Menu Tutorial

Written by Kevin Liew on 19 Mar 2009
669,183 Views • Shares
183 comments

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
Lenin Ocaña 9 years ago
Hello this tabs are great thanks. I retrieve the tab info from a database and fill it with AJAX dinamically, but when I do this I cant make works the slide effect you used on category tab.

Do you know how to do to still working the slide effect after a content refreshing?

thank you?
Reply
eljay 9 years ago
I have this working just fine - however there are two things I would like to do but can't seem to be able to figure out - any tips would be greatly appreciated!
1- I want to replace the list with two divs, a left and right div (column) containing images and text.
2- I want to remove the 'slide' up and down animation and just have the content appear instantly on click.

Thanks!

eljay
Reply
Daniel Van Der Werken 9 years ago
Why did you use .Mouseover and .Mouseout instead of .hover?

Reply
Carlos Gomes 9 years ago
Hey, kenvin,

Would you give me a heads up on how to make it load from a SQL db, cause i'm kinda stucked?

Thanks in advance
Reply
Jarod Billingslea 9 years ago
use the hover(), instead of mouseout() and mouseover(), like this:

$(selector).hover(function() {
// mouseover
}, function() {
// mouseout
});
Reply
kavitha 9 years ago
Nice
Reply
Olivier 9 years ago
Nice one.
Has anyone managed to combine it with a 'toggle' function.
I need to hide all the content, and only display it when a tab is clicked ...

Thanks
Reply
Jay 9 years ago
@Jarod - Can you explain in detail with a cut/paste of what to replace sample?
Reply
John 9 years ago
Why even use javascript for an image hover when it can be done with css?! Only thing that needs js is the switching of content and sliding effect.
Reply
moke 9 years ago
excellent.............!!!!!!!!!!!!!
Reply
Frank Jansen 9 years ago
Great tabs setup!

I am struggling with one thing though: the limitation that there can be no nested divs. I'm trying to get Nivo Slider working within one of the tabs, but it needs to be within a div itself. Has anyone overcome this?

Thanks!
Reply
Kevin Liew Admin 9 years ago
I can help you to solve it. It was my bad, wasn't thinking it through when I first made it. I was learning how to use jQuery. I think you can fix it my modify this line of jquery script:

//Hide all the DIV in .boxBody
$('.boxBody div').slideUp('1500');

to

//Hide all the DIV in .boxBody
$('.boxBody div:first-child').slideUp('1500');

Reply
Frank Jansen 9 years ago
Kevin,

thank you for the response. I just ran a quick test and it adjusted some of the behavior, but had some other side-effects. I'll poke around a little more.

Appreciate your work!

Frank
Reply
Frank Jansen 9 years ago
Kevin,

a quick update. After quite a bit of digging and rooting through jQuery (and some learning on my part), I have found a selector that works:

$('.boxBody > div:eq(' + $('#tabMenu > li').index(this) + ')').find('*').andSelf().slideDown('1500');

Thanks again for this tutorial, as it got me going in the right direction.

Frank
Reply
Alex 8 years ago
A great tool, many thanks for it!
I have recently come across the nested div problem and tried both suggested fixes for it in the jquery and had no luck.
Any other ideas for me to try?
Reply
Eduardo 9 years ago
I´m having problems when I try to use a form inside the boxBody. Somebody can help me, please?
Reply
Kevin Liew Admin 9 years ago
it should be alright. what's the problem?
Reply
Martie 9 years ago
Is there a way to make the box a fixed size instead of having the box fit to the content? I want to have a fixed content size and add my own scrollbar for overflow
Reply
Pete 9 years ago
Yep... adding height: XXXpx; to the .boxBody does the trick
Reply