Themeforest

jQuery Simple Vertical Accordion Menu

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;
}
  • jQuery Social Stream Plugin
  • jQuery Social Media Tabs Plugin

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.

Also Check Out Our Premium jQuery Plugins:

127 Comments

  • 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.. 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 ..

          <li><a href="google.com">Accueil</a> => doesn't open anything
          </li>
        

        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

  • 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.

  • 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;}