A Simple and Beautiful jQuery Accordion Tutorial

Written by Kevin Liew on 30 Sep 2009
133,755 Views • Tutorials

Introduction

I was about running of ideas in tutorials, picking my own brain, and finally, I've almost forgotten the awesomeness of accordion. Yes, we will be creating a Accordion! Accordion has several characteristics:

  • Normally, the menu is displayed vertically (I have seen a horizontal one though)
  • Click on an item, it will expand its submenu and hide other submenu
  • Usually, an Accordion has indicators to show the state of the menu

So, yes, we will do that with the minimal amount of code, clean html and good looking images.

1. HTML

In this section, we use UL List to form the structure. The first level UL will be the navigation menu, and the second level UL that resides inside each first level UL's LI will be the submenu.

There is some rules over here about the classes and rel attribute, let me explain:

  • .popular, .category, .comment Classes in the anchor element (first level) are used for the styling of the menu.
  • Rel atribute in the anchor element (first level) is used by javascript to add and remove "selected state" aka change the menu image after it was clicked
  • .item class is required for each heading item
  • .last Class is used to remove border bottom for the last item
<ul id="accordion">
	<li>
		<a href="#" class="item popular" rel="popular">Popular Post</a>
		<ul>
			<li><a href="#">Popular Post 1</a></li>
			<li><a href="#">Popular Post 2</a></li>
			<li><a href="#" class="last">Popular Post 3</a></li>
		</ul>
	</li>
	<li>
		<a href="#" class="item category" rel="category">Category</a>
		<ul>
			<li><a href="#">Category 1</a></li>
			<li><a href="#">Category 2</a></li>
			<li><a href="#" class="last">Category 3</a></li>
		</ul>
	</li>
	<li>
		<a href="#" class="item comment" rel="comment">Recent Comment</a>
		<ul>
			<li><a href="#">Comment 1</a></li>
			<li><a href="#">Comment 2</a></li>
			<li><a href="#" class="last">Comment 3</a></li>
		</ul>
	</li>
</ul>

2. CSS

CSS is pretty simple, we are using two UL Lists. So, what we do is, style the first level UL, skin it with images, and after that, style the second UL List and hide it.

Have you heard about CSS Sprite? CSS Sprites are the preferred method for reducing the number of image requests. Combine your background images into a single image and use the CSS background-image and background-position properties to display the desired image segment. Yes, this is the image we are using for this tutorial:

CSS Sprite Menu Layout

And, if you wish to learn more about CSS, you can read my previous posts:

/* First Level UL List */
#accordion {
	margin:0;
	padding:0;	
	list-style:none;
}
	
	#accordion li {
		width:267px;
	}
	
	#accordion li a {
		display: block;
		width: 268px;
		height: 43px;	
		text-indent:-999em;
		outline:none;
	}
		
	/* Using CSS Sprite for menu item */
	#accordion li a.popular {
		background:url(menu.jpg) no-repeat 0 0;	
	}

	#accordion li a.popular:hover, .popularOver {
		background:url(menu.jpg) no-repeat -268px 0 !important;	
	}
		
	#accordion li a.category {
		background:url(menu.jpg) no-repeat 0 -43px;	
	}

	#accordion li a.category:hover, .categoryOver {
		background:url(menu.jpg) no-repeat -268px -43px !important;	
	}
		
	#accordion li a.comment {
		background:url(menu.jpg) no-repeat 0 -86px;	
	}

	#accordion li a.comment:hover, .commentOver {
		background:url(menu.jpg) no-repeat -268px -86px !important;	
	}
		
		
	/* Second Level UL List*/
	#accordion ul {
		background:url(bg.gif) repeat-y 0 0;
		width:268px;
		margin:0;
		padding:0;
		display:none;	
	}
		
		#accordion ul li {
			height:30px;
		}
			
		/* styling of submenu item */
		#accordion ul li a {
			width:240px;
			height:25px;
			margin-left:15px;
			padding-top:5px;
			border-bottom: 1px dotted #777;
			text-indent:0;
			color:#ccc;
			text-decoration:none;
		}

		/* remove border bottom of the last item */
		#accordion ul li a.last {
			border-bottom: none;
		}	

3. Javascript

There are two major sections in this javascript click event:

  • First section: Reset everything back to default. What it does, hide all the submenus and also reset all the arrow to default position.
  • Second section: Display the selected item and change the arrow direction

It gets a little bit tricky in resetting the arrow back to default position. I'm using for each method to loop thorugh the menu, grab its REL and and remove the classes. I think there are different ways to accomplish it. If you do know a better way, please let me know and I will ammend it.

	
$(document).ready(function () {
		
	$('#accordion a.item').click(function () {

		/* FIRST SECTION */
	
		//slideup or hide all the Submenu
		$('#accordion li').children('ul').slideUp('fast');	
		
		//remove all the "Over" class, so that the arrow reset to default
		$('#accordion a.item').each(function () {
			if ($(this).attr('rel')!='') {
				$(this).removeClass($(this).attr('rel') + 'Over');	
			}
		});
		
		/* SECOND SECTION */		
		
		//show the selected submenu
		$(this).siblings('ul').slideDown('fast');
		
		//add "Over" class, so that the arrow pointing down
		$(this).addClass($(this).attr('rel') + 'Over');			
	
		return false;

	});

	
});

Conclusion

Like this tutorials? You can express your gratitude by visiting my sponsors on the sidebar, bookmark it and help me to spread this tutorial to our friends! :) Thanks!

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.

55 comments
Amit 12 years ago
I hjave used..this code from accordian tutorial and made it dynamic and verified.. that structure .. is totally same. But i m facing problem to call click() method by clicking on main menu ..
Please help me out
Reply
Yuva 11 years ago
Hi,
Can you share the sample code that is dynamically populated. Are you using the Struts2/Tiles for this.
Yuva
Reply
jessy 12 years ago
Hi, Thanks for this great Tut. But i have small issue in the script when i tried to open it in IE 8, I am using the onclick function script, after the accordion open i see the equal number <div> tag showing at the bottom of the page to the same number tabs in accordion li. Will be much helpful, If you reply. Thanks.
Reply
Maciej 12 years ago
How to get index of active part ( index of clicked ul ) ??
Reply
Stephanie 11 years ago
Hello,

How do you re-collapse an item? I would like to be able to open and close it. Currently you click on the one that is open and it pops up then back down. Thanks!
Reply
reza 9 years ago
tnx it was nice
Reply