Simple WordPress Accordion Menu

So when WordPress introduced the wp_nav_menu() function, it made it easier to create navigation menus for the average user. You can create dropdown navigation simply moving the items around in the admin -> appearance -> menu section of your dashboard. This tutorial requires jQuery, but is not a jQuery plugin. See live demo I installed at: http://www.belocalnc.org. For example, try clicking on "For Business" and then "Membership" and then on "For Community." The nav collapses appropriately and stays open to the last item clicked on the resulting page. The code here is CSS and a few of jQuery that are effective and work well with the generated menus from wp_nav_menu(). First you must make sure that your current theme supports these types of menus. Add this to your themes "functions.php" if it is not already there.
add_theme_support('menus');
register_nav_menus(
        array(
          'primary_navigation' => 'Primary Navigation',
          'utility_navigation' => 'Utility Navigation' // i like to set up a couple at first in case i need them later
        )
);
Here is the html in your header.php
<nav id="nav-main" role="navigation">
        <?php wp_nav_menu(array('theme_location' => 'primary_navigation')); ?>
</nav>
Now here is the CSS for the nav
// Portions adapted from http://rootstheme.com
// The CSS here is slightly different from the live demo as i didn't include any of the images that are on the live site
#nav-main ul { list-style: none; margin: 0; padding :0; text-align: left; }
#nav-main ul a {
  display: block;
  text-decoration: none;        
}
#nav-main ul li { display:inline-block; width: 100%;} 
#nav-main ul li a { 
        text-decoration:none; 
        display:block; 
        font-size:1.0em; 
        padding: 10px 0px 10px 25px; 
        color:#464646; 
        margin: 0px 0px;
        border-top: 1px #a9aaa9 solid;
        letter-spacing: 1px;
}

#nav-main ul li a:hover { background: #ffffff; }
#nav-main ul li ul li a:hover { background: none; color: #0f6cb6; }
#nav-main ul li ul { position: relative; top: -2px; }

#nav-main ul ul li a { background: none; border: none; padding: 2px 0px 2px 0px; margin: 0 0 0 27px; }
#nav-main ul ul li ul { margin: 0 0 0 8px; }

ul.sub-menu li.current-menu-item  { color: #0f6cb6 !important; font-weight: bold; }
Lastly, we can add this to either your themes "scripts.js" file, or just in your header.php
  // Portions of this were adapted from "http://www.i-marco.nl/weblog/jquery-accordion-menu/".
  // It only went one level deep.
  // This now accounts for more levels of accordion.

$(document).ready( function($) {

  // This hides all the sub menus on page load
  $('#nav-main ul.sub-menu').hide();
  // This makes sure that all the sub menus are open when applicable
  $('#nav-main li.current-menu-item').children().show();
  // This keeps the nav open to the item that you are navigating to.
  $('#nav-main li.current-menu-item').parents().show(); 

  $('#nav-main ul li a').click(
    function() {
      var checkElement = $(this).next();
      if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
        return false;
        }
      if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
                $(this).parent().siblings("li:has(ul)").find("ul").slideUp('normal');                   
        $('#nav-main ul ul li ul:visible').slideUp('normal');
        checkElement.slideDown('normal');
        return false;
        }
      }
    );
  $('#nav-main ul ul li a').click(
    function() {
      var checkElement = $(this).next();
      if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
        return false;
        }
      if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
        $('#nav-main ul ul').slideUp('normal');    
        $('#nav-main ul ul li ul:visible').slideUp('normal');
        checkElement.slideDown('normal');
        return false;
        }
      }
    );  

});
Post a comment
  1. Erica

    Hi Matthew, this code works perfectly for me, but I haven't been able to figure out how to make it work with linked parent items. My structure is category archive > post, and I'd like the primary navigation items (the category archives) to link to their archives while also expanding the submenu of posts. Any insight you could give me would be fantastic.

  2. jimmy

    yes

    • Matthew Price

      ok, so are there any errors in the console when you insert the extra code? i.e. the inspector in firefox, safari, or chrome? i am imagining that there is probably an error and that is causing the rest of the JS to not execute and therefore causing the menu to be open. If i had to take a guess it is that there is some kind of conflict mode issue...ie jQuery vs $ lemme know what if any errors you see? is there a url i can see? if you don't want to post it here, feel free to email me: [email protected]

  3. jimmy

    Hi Matthew thanks for the fast responce - I tried adding the code to header.php, the script.js and each time and each time it just forces the menu to display open all i am trying to achive is put a + sign so that users know there is sub menus then i hope to add the fuctionality to - and close cheers for the help once again

    • Matthew Price

      so if you do not include this code, does the menu function correctly?






Real Time Web Analytics ^