Today’s jQuery tutorial is a perfect example of how easy it is to add a slick vertical accordion style menu to your website with just a few lines of jQuery code!
The HTML
First we create a nested unordered list, which will include all of our links. Give the first ul tag a unique id – we use #nav:
<ul id="nav">
<li><a href="#">Item 1</a>
<ul>
<li><a href="#">Sub-Item 1 a</a></li>
<li><a href="#">Sub-Item 1 b</a></li>
<li><a href="#">Sub-Item 1 c</a></li>
</ul>
</li>
<li><a href="#">Item 2</a>
<ul>
<li><a href="#">Sub-Item 2 a</a></li>
<li><a href="#">Sub-Item 2 b</a></li>
</ul>
</li>
<li><a href="#">Item 3</a>
<ul>
<li><a href="#">Sub-Item 3 a</a></li>
<li><a href="#">Sub-Item 3 b</a></li>
<li><a href="#">Sub-Item 3 c</a></li>
<li><a href="#">Sub-Item 3 d</a></li>
</ul>
</li>
<li><a href="#">Item 4</a>
<ul>
<li><a href="#">Sub-Item 4 a</a></li>
<li><a href="#">Sub-Item 4 b</a></li>
<li><a href="#">Sub-Item 4 c</a></li>
</ul>
</li>
</ul>
Style The Menu With CSS
For this tutorial we add a little styling to the menu and use CSS to hide the sub-menus using “display: none;”:
#nav {
float: left;
width: 280px;
border-top: 1px solid #999;
border-right: 1px solid #999;
border-left: 1px solid #999;
}
#nav li a {
display: block;
padding: 10px 15px;
background: #ccc;
border-top: 1px solid #eee;
border-bottom: 1px solid #999;
text-decoration: none;
color: #000;
}
#nav li a:hover, #nav li a.active {
background: #999;
color: #fff;
}
#nav li ul {
display: none; // used to hide sub-menus
}
#nav li ul li a {
padding: 10px 25px;
background: #ececec;
border-bottom: 1px dotted #ccc;
}
The jQuery Code
To create the accordion effect the code is extremely simple:
$(document).ready(function () {
$('#nav > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$('#nav li ul').slideUp();
$(this).next().slideToggle();
$('#nav li a').removeClass('active');
$(this).addClass('active');
}
});
});
First we use the child selector “>” to ensure that only the parent links activate the accordion menu – otherwise you would end up closing the menu each time a sub-link is clicked.
We add a new class to the active item – this allows us to not only style the open accordion menu but also identify if a sub-menu is open when a link is clicked. The above jQuery code will only work on closed menu items.
View the jQuery vertical accordion menu demo.
Update 5th Mar 2011:
We have now also released the jQuery Vertical Accordion Menu Plugin, which makes it easy to create accordion menus from any nested HTML lists. The plugin has several features including use of cookies and ability to select either hover or click to activate the menu.
Check out the project pages for more information and examples or go straight to the download page.


















Hi Lee
I have been asked for the other menus not to close hen you click on another menu item.
E.G
Click On Item One – Expands
Click On Item Two- Expands
And the only way to get the items to close again would be to click on them again.
Hope that makes sensde, and you can help.
Many Thanks for this!!
Hi,
May be easier to use the jQuery vertical accordion menu plugin, which includes options to expand the menu as per your requirements – http://www.designchemical.com/lab/jquery-vertical-accordion-menu-plugin/getting-started/
hi.. how can i get active colours on sub menu??? ie. when i click a main menu its showing its highlighted colur as an active one… but im not able to set active colour on sub menu since i hav many… i badly need it…!
Either use a cookie to remember which one was clicked or set the active state in the HTML when the menu is generated for the page
hey, great plugin.
i just start using it, and i wanted to ask you, how i can put another “sublevel” inside.
for example.
Item 1
Sub-Item 1 a
Sub-Item 1 a 1
Sub-Item 1 a 2
i mean
inside a sublevel, put another one, like play with 3 depths.
any idea?
Hi,
Just add another sub-menu to the menu. The plugin will automatically handle it
[...] http://www.designchemical.com/blog/index.php/jquery/jquery-simple-vertical-accordion-menu/ is a great fast accordion plugin and http://perishablepress.com/slide-fade-content/ is a great fast ajax plugin to put some content in a div. Just style it and go! [...]
Hey Lee,
Thanks for the code. If I wanted to default the first list item to be expanded on the page load, how would I go about doing so?
Thanks.
Hi,
You can add
$('#nav li:first ul').show();Hello,
first, i would like to thank you for sharing this code, it is very helpfull for me.
I’ve successfully integrated your menu on my test website but i would like to know if it is possible to let the submenu opened when i click on a submenu link ?
Thanks
Hi,
Not sure if this is what you mean – jQuery Simple Vertical Accordion Menu with Cookies
Thanks for your reply.
The result is ok but it seems a little overpowered for my needs.
Exemple : i click on the submenu item 1 => the page load and the menu close the section 1 .. i want that the clicked submenu stay open (only for this session, no need for cookies).
Also, if i set a link to a li item, i can click on it but the link doesn’t open, only li contained in ul elements seems to work ..
Thanks a lot
You still need some way of storing the variable between pages. You can use a session as you suggest but you will need to add the code that creates the session variable. Retrieve whatever sesssion variable you save and then use that to open the corresponding sub-menu on page load
Hi please tell me how to change the color of currently active menu.
Hi,
The active menu item is given the CSS class “active” so you can style the link in your CSS style sheet using #nav li a.active {}
So I would like to have the nested ul load in the expanded state depending on the page it’s on. i.e. show the nested menu item as active. How do I do this? Thank!
Hi,
You can set the class of the relevant link item to “active” and then add the following jquery, which will open the sub-menu of the active item:
$('#nav a.active').each(function(){ $(this).next().show(); });I would like to ask you: is it possible to change your menu from mouse-click to mouse-over? Thank you for your reply. Vasek
Hi,
Yes there is already a demo for this – Simple Vertical Accordion Menu – Using Hover
Hello, I would like to ask you – where I should put the jQuery code? I would like to put this accordion to my Blogger templates…. Thank you very much! Vasek
Hi,
Follow the source code for the demo page – you should see the code to load the jquery library and the code to create the accordion menu
Thank you for your advice, it works
I have a question. How do you add this into a dreamweaver cs5 page? i don’t know what jquery is and any info on how to add it into the actual document would be great.
Hi – you are probably better using the plugin version, which has more options and should be easier to use. Instructions can be found at – http://www.designchemical.com/lab/jquery-vertical-accordion-menu-plugin/getting-started/
I just built the menu, but the sub categories still have bullets by them and the frame of it is distorted. Here is the code:
#nav {float: left; width: 280px; border-top: 1px solid #999; border-right: 1px solid #999; border-left: 1px solid #999; margin-bottom: 15px; list-style:none;}
#nav li a {display: block; padding: 10px 15px; background: #ccc; border-top: 1px solid #eee; border-bottom: 1px solid #999; text-decoration: none; color: #000; list-style:none;}
#nav li a:hover, #nav li a.active {background: #999; color: #fff; list-style:none;}
#nav li ul {display: none;}
#nav li ul li a {padding: 10px 25px; background: #ececec; border-bottom: 1px dotted #ccc; list-style:none;}
$(document).ready(function () {
$(‘#nav > li > a’).click(function(){
$(this).next().slideToggle();
if ($(this).attr(‘class’) != ‘active’){
$(this).addClass(‘active’);
} else {
$(this).removeClass(‘active’);
}
});
});
Item 1
Sub-Item 1 a
Sub-Item 1 b
Sub-Item 1 c
Item 2
Sub-Item 2 a
Sub-Item 2 b
Item 3
Sub-Item 3 a
Sub-Item 3 b
Sub-Item 3 c
Sub-Item 3 d
Item 4
Sub-Item 4 a
Sub-Item 4 b
Sub-Item 4 c
Hi. Try using the following CSS:
#nav {float: left; width: 280px; border-top: 1px solid #999; border-right: 1px solid #999; border-left: 1px solid #999; margin-bottom: 15px;} #nav, #nav ul, #nav li {list-style:none;} #nav li a {display: block; padding: 10px 15px; background: #ccc; border-top: 1px solid #eee; border-bottom: 1px solid #999; text-decoration: none; color: #000;} #nav li a:hover, #nav li a.active {background: #999; color: #fff;} #nav li ul {display: none;} #nav li ul li a {padding: 10px 25px; background: #ececec; border-bottom: 1px dotted #ccc;}Hi again,
I was able to accomplish what I was trying to do (get all the menu bars the same color) by removing the #D7D4D4 url (skins/images/bg_grey.png) and replacing the whole thing with just my color choice and nothing else. That did the trick and I like the way it looks. I’m going to be messing around with a couple more customizations, so I might be back looking for help. I’m new to all this.
Thank you!
OK great. Make sure you copy the customised style sheet to your theme files folder as all plugin files are automatically deleted and updated by WordPress whenever a plugin revision comes out
Hi Lee,
I’m just beginning to get a web site set up and am using the latest version of the jQuery Accordion Menu. I’m very happy with it but wanted to customize the colors and can’t seem to get one of the menu blocks to match the others; it remains in the original grey color. It happens to be the only menu block with sub-menu items so I suspect that has something to do with it but can’t figure out what I need to change. Can you help?
Thank you!
Hi. You need to change the CSS for the following:
#dc_jqaccordion_widget-4-item ul a.dcjq-parent
That did the trick, thanks a bunch. any opinions you’d like to share on the development site? its still a work-in-progress.
hey Lee, thanks alot for providing excellent resources here. i’m slowly coming to grips with all this JS.
One quick question, ive used your script here but applies it to a normal bullet list. its works great. the only thing is that every time i click on the first ‘s the browser scrolls the page all the way up! as if its a page refresh or sthg. here it is in effect. http://www.omarsabet.com/behman/services.php
any ideas how i can remedy this ? thanks alot for your time good sir.
Hi – Change the jQuery in your site to the following:
$('#accordion > li > a').click(function(e){ if ($(this).attr('class') != 'collapsed'){ $('#accordion li ul').slideUp(); $(this).next().slideToggle(); $('#accordion li a').removeClass('collapsed'); $(this).addClass('collapsed'); } e.preventDefault(); });The e.preventDefault(); will stop the browser scrolling to the top of the screen when the link containing ‘#’ is clicked
Hi Lee, awesome menu!
I tried simplify the style to get a more typographic styl.
Everything works out fine but I can’t get writ of the bullets in front of the menu. I tried “list-style-type: none;” on the “ul”, “ul li” & “ul a” but no luck so far. Can you give me some pointers?
Thanks!
Heyman
Hi Heyman – have you tried ul {list-style: none;}?
Hi Lee,
Don’t worry about that last request.
I found out how I could apply a css class to the CMS generated UL id which meant I could then use your Plugin version (http://www.designchemical.com/lab/jquery-vertical-accordion-menu-plugin/getting-started/) instead of this simple version
This solved my problem… great scripts by the way!!!
Hi Rick – OK great. The plugin does offer a lot more options/flexibility
Hi Lee
really like this light weight script.
Can you please give some advise on how to get the “li” and “li ul li” items to show as active?
I cannot seem to get them to show the item that is active in relation to the page showing.
Also the slider doesn’t stay open to show the active “li ul li” item so you can then select another menu item in that sub slider.
Hope that makes sense.
For reference here is a link to the site I am trying to integrate this menu into:
http://nzbusiness7.businesscatalyst.com/
There a few to choose from but the second and 3rd menu items both have the accordion slider.
My script info is:
$(document).ready(function () {
$(‘#nav_826250 li a’).click(function(){
if($(this).next().length){
if ($(this).attr(‘class’) != ‘active’){
$(‘#nav_826250 li ul’).slideUp();
$(this).next().slideToggle();
}
}
$(‘#nav_826250 li a’).removeClass(‘active’);
$(this).addClass(‘active’);
});
});
and my CSS is as follows:
/*—– accordion menu css ———*/
#nav_826250 {float: left; width: 189px; margin: 20px 0 0 10px;padding: 0;display: block;list-style-type: none; font-family: ‘Helvetica’,Verdana,Lucida,Geneva,Helvetica,Arial,sans-serif;font-size: 9pt;font-weight: bold;}
#nav_826250 li a { border-bottom: 1px solid #555555;
border-top: 1px solid #888888;
color: #FFFFFF;
display: block;
padding: 5px 20px;
text-decoration: none;
width: 149px;}
#nav_826250 li:first-child a {
background-position: 8px center;
background-repeat: no-repeat;
border-bottom: 1px solid #555555;
border-top: 1px solid #666;
color: #FFFFFF;
display: block;
padding: 5px 20px;
text-decoration: none;
width: 149px;
}
#nav_826250 li a:hover, #nav_826250 li a.active, #nav_826250 li ul li a:hover, #nav_826250 li ul li a:active,#nav_826250 li ul li:first-child a:hover, #nav_826250 li ul li:first-child a:active {background: #555; color: #ffcc66; border-top: 1px solid #444;background-image: url(/images/arrowa1.gif);
background-position: 8px center;
background-repeat: no-repeat;
}
#nav_826250 li ul { margin: 0;padding: 0;display: none;list-style-type: none;width: 189px;font-weight: normal;}
#nav_826250 li ul li a, #nav_826250 li ul li:first-child a {
background: none repeat scroll 0 0 #FFCC66;
border-bottom: 1px solid #E1B45B;
border-top: 1px solid #FFE470;
color: #444444;
font-size: 8.5pt;
width: 149px;
}
#nav_826250 li ul li:first-child a:hover, #nav_826250 li ul li:first-child a:active,#nav_826250 li ul li a:hover, #nav_826250 li ul li a:active {border-bottom: 1px solid #444444;}
#nav_826250 li ul li: a.active {background: #000; color: #fff;}
ul.active {background: }
/*—– end of accordion menu css ———*/
Any help would be appreciated.
Thanks for this Lee,
after changing the code, it seems to only perform the function once, so if i open then close, it wont slide down again ?
Hi Nick – sorry, didnt check that. Change the jQuery code to the following:
$('#nav > li > a').click(function(){ $(this).next().slideToggle(); if ($(this).attr('class') != 'active'){ $(this).addClass('active'); } else { $(this).removeClass('active'); } });See Demo
Hi Lee,
thankyou for the vertical menu!
But I would like to ask, how do I edit the javascript so that once Item 1 has been ‘activated’ it can be clicked again and slide back up. Instead of relying on another Item to be clicked to slide up.
Thankyou
Nick
Hi Nick – just move the 3rd line above the if statement so the jQuery becomes:
$('#nav > li > a').click(function(){ $('#nav li ul').slideUp(); if ($(this).attr('class') != 'active'){ $(this).next().slideToggle(); $('#nav li a').removeClass('active'); $(this).addClass('active'); } });See updated accordion menu demo
Hi Lee i give you a link with the site http://samara-tours.com/new/samara_beach_tours/arenal_volcano.html