You are Viewing : HomeBlogsWordPress dropdown menu with wp_nav_menu and CSS

WordPress dropdown menu with wp_nav_menu and CSS

WordPress 3.0 came with quite a number of awesome and useful features. That includes native navigational menus, which can be customized through the WordPress admin. (Dashboard –> Appearance –> Menus) . Many themes released nowadays support native menus. Let us learn how to add some Native menu support.

This is part 1 of the dropdown menu series.

To check whether your theme has native menu support, Proceed to “Wordpress admin-> Appearance –> Menus” (WordPress 3.0+ only) . If there is no support, following message will be displayed.

1_no_menu_support

Look! No native menu support.

We can add the support by following through the below guide. Since it is not advisable to play with your blog’s theme, I have made a simple theme just for this purpose. It is a mod of Famous Kubrick of WP 2.0, and is named Axtra.  If possible, definitely try this on a local server in your Mac or windows.

{filelink=1}

wp_page_menu(); aka WordPress 3.0+ native menus support

wp_nav_menu() function does the work of displaying the wordpress menus that can be completely and easily customized through the admin. [codex reference]

Following code displays the menu.

<?php wp_nav_menu(); ?>

Like most wordpress functions do, wp_nav_menu() accepts arguments.

<?php wp_nav_menu(array( ‘theme_location’ => ‘Main-Menu’)); ?>

Complete arguments list is available in WordPress codex, Below are the options that we will be using through out this walkthrough.

  1. theme_location : Theme location, i.e. Location of the menu in the theme structure.
  2. menu_class: CSS class for the menu. (Default is ‘menu_class’ => ‘menu’).
  3. fallback_cb : Fallback wordpress function to call, when wp_nav_menu is un available. default is wp_list_pages.
  4. container_id : CSS ID to be assigned to the container(default is DIV tag) that wraps around the menu.
  5. container_class : Similar to above, but this is CSS class.

Adding wp_nav_menu support to your theme

This involves the following procedure.

  1. Register the menu : This can be done using register_nav_menu or register_nav_menus and initializing them.
  2. Display the menu : Add wp_nav_menu function to the theme, wherever you want the menu to appear.
  3. Style the menu : The key is adding the menu CSS class to wp_nav_menu and using that class with the CSS or JS dropdown solution.

Registering the menu

Open the theme’s function.php. If it is not present in your theme’s root directory, create a new file with the same name. Always name it in lowercase.

First thing to do is registering the menu location, through register_nav_menus() [Codex reference]

using register_nav_menus -

// Create a function for register_nav_menus()
function add_wp3menu_support() {

register_nav_menus(
		array(
		'main-menu' => __('Main Navigation'),
		'another-menu' => __('Another Navigation')
		)
	 );

}

//Add the above function to init hook.

add_action('init', 'add_wp3menu_support');

Good. Now theme has two menus, first one – registered as  “main-menu” – used to display the Main navigation below the header, and second – “another-menu” which may be used for diverse purposes (For e.g. add a menu to sidebar, custom post). The menus are to be initialized with the theme through wp_head() hook.

Display the menu

Now the registered menus need to be displayed. Here comes wp_nav_menu to the rescue. Insert the following code in the theme, where you want the menu to appear.

Usual location would be just below the header. I chose to include this in header.php , below the header div tag. I also added a div container around the menu with the CSS ID “navigation” (which can be used later for centering the menus).

<!-- a container that wraps around.-->
<div id="navigation">

<?php wp_nav_menu(); //displays the menu?>

</div><!-- end #navigation -->

Well, this displays the menu. Now we have two concerns. First – we registered two menus and second – we need to add dropdown menus in the next step. wp_nav_menu has got arguments that we can make use of.

<div id="navigation">

<?php
          wp_nav_menu( array(
	'theme_location' => 'main-menu', // Setting up the location for the main-menu, Main Navigation.
	'menu_class' => 'dropdown', //Adding the class for dropdowns
	'container_id' => 'navwrap', //Add CSS ID to the containter that wraps the menu.
	'fallback_cb' => 'wp_page_menu', //if wp_nav_menu is unavailable, WordPress displays wp_page_menu function, which displays the pages of your blog.
	)
      );
?>

</div>

Let us look at the above code.

  • ‘theme_location’ refers to the location of the menu in the theme.
  • ‘menu_class’ refers to CSS class that is going to be used for dropdown menu.
  • Similarly ‘container_id’ is the CSS ID for the div that surrounds the Navigation.
  • ‘fallback_cb’ points to the function that will be used in case wp_nav_menu is not available. Default for ‘fallback_cb’ is the function wp_list_pages().

This completes setting up the “main-menu”. Similarly setup the “another-menu” for better idea.

Congratulations. Now your theme has wordpress 3.0 Menus support. Now check “Dashboard –> Appearance –> Menus”. The “no support” message is gone! Yes, you should now be able to create custom menus (Hint: Button “Create Menu”).

If you encounter any problems, verify with the included (modified) functions.php and header.php below.

{filelink=2}

Styling the menu with Superfish and similar

This is covered in a separate article here.

Creating a Menu via WordPress admin

  1. Proceed to “WordPress admin –> Appearance –> Menus”.
  2. Enter the menu name and Click “Create Menu”. You should now see a message “The your_menu_name_here menu has been successfully created.”
  3. Now you can add custom links, pages or categories to your menu.
        1. In the custom Links field, you can enter the URL and Label(name it goes by) and click “Add to Menu”.
        2. In the Pages, Check those you need to appear in menu and click “Add to Menu”.
        3. Similarly add those in the categories.
        4. Now click “Save Menu”.
        5. Simply drag above and below to re-order and drag left and right to (un)indent the menu items.
        6. It is simpler and better if you have up to 3 levels of menu.
  4. Look in the first box under “Theme locations”. Now select the menu you just created in the combo box “Primary Navigation”. Remember, We named our “main-menu” as “Primary Navigation”. Click Save.

    menu_added

    Your Menu has been successfully created.

Well done. Now reload and check your index page. Menu appears, but looks hideous.

unstyled_menu

Hmm.. Not quite what we expected.But wait!

Untitled-3

Throwing in some css, Now it looks neat. and with No images.

And the CSS involved, with some explanation.

/* The container wrapping ul.dropdown */
#navwrap {
float:left;
width:100%;
background: #600;
background: -moz-linear-gradient( top, #600, #300); /* CSS 3 */
font: 1.0em "Segoe UI", "Lucida Grande", Verdana, Arial, sans-serif;
border-top:1px solid #999;
border-bottom:2px solid #000;
}

/* Top level Unordered list */
ul.dropdown {
list-style:none;
float:left;
width:100%;
padding: 0 10px;
}

ul.dropdown  li{
float:left; /* makes horiz list */
position:relative; /* hey Submenu ULs, appear below! */
}

ul.dropdown a {
padding:12px; /*space the items, occupy entire height too.*/
color:#eee;
text-decoration:none;
text-shadow:0 1px 0 #000;
}

/* Style the link hover */
ul.dropdown li:hover a {
background:#444;
border-top:1px solid #777;
border-bottom: 1px solid #000;
border-right:1px solid #666;
}

/* Displays the link as blocks. */
ul.dropdown li ul a {
display:block;
}

/* sub menus!!  */

ul.dropdown ul {
list-style: none;
margin:0; /* Appear just below the hovering list */
padding:0;
width:200px; /* specify the width. */
position:absolute; /* needed */
z-index:500; /* specify the order */
}

ul.dropdown li ul {
top:27px; /* Positioning:Calc with top level horz list height */
-moz-box-shadow:0 2px 10px #000; /* CSS 3 */
}

ul.dropdown ul ul {
top:0;
left:100%; /* Position the sub menus to right. */
}

ul.dropdown ul li {
float:none; /* umm.. Appear below the previous one. mmkay? */
}

/* Drop Down! */

/* Hide all the dropdowns (submenus) */
ul.dropdown ul,
ul.dropdown li:hover ul ul,
ul.dropdown ul li:hover ul ul
{ display: none; }

/* Display the submenus only when li are hovered */
ul.dropdown li:hover ul,
ul.dropdown ul li:hover ul ,
ul.dropdown ul li ul li:hover ul
{ display: block;}

ul.dropdown li * a:hover {
/* Change color of links when hovered */
background: #600;
background: -moz-linear-gradient( top, #200, #400); /* CSS 3 */
border-bottom:1px solid #900;
border-top:1px solid #222;
}

Upcoming

Part 2 of this Guide – WordPress dropdown menu with superfish

Part 3 of this Guide – WordPress dropdown menu with CSS3.


Reference

WordPress codex reference : register_nav_menus()

WordPress codex reference : wp_nav_menu()

WordPress codex reference : wp_page_menu() and wp_list_pages

  • senbalan

    useful post

    • http://kav.in kavin

      Thank you, Mr Senbalan.

  • Pingback: Add a Superfish Dropdown menu to wordpress | Capability

  • http://zebardast.ir/en Saeid

    great tutorial. thank you.

    • http://kav.in kavin

      Thanks :)

  • http://ameetkarn.info Ameet

    awesome bro u saved my a** was desperately looking for it

  • Pingback: wp-popular.com » Blog Archive » Navigation Menu Dropdows

  • http://hajaluz.webluz.net Luiz Aquino

    Great tutorial, the best and more simple solution to menu drop down in wordpress.

    You help me a log buddy.

    Hugs from Brazil :-) ))

    • http://kav.in kavin

      Thanks Luiz. :D . You’re welcome.

  • http://elturan.com EL

    Thanks a lot!

  • maha

    Thanks

  • ollie

    I got this error after entering the code into the functions.php

    Any help?

    ‘Parse error: syntax error, unexpected T_STRING in ROOT/wp-content/themes/Theme_Template/functions.php on line 166′

    • http://kav.in kavin

      This is a common php error mostly caused by typos. Verify the lines 166 and 165 for any missing quotes Double quote ( ” ) , single quote( ‘ ) or semicolons( ; ). If you are not completely sure, post the contents of the theme_template/functions.php to pastebin.ca , so that i can look at it.

      • ollie

        Ok, everything seems to be working now, i don’t quite know what my problem was but it is fixed now.
        Thank you very much for this awesome tutorial, perfect for what i need for my web design client.. Life saver.

        • http://kav.in kavin

          You’re welcome, Ollie.

    • ollie

      I fixed it by putting this in the functions file:

      add_action( ‘wp_head’, ‘add_our_scripts’,0);

      • ollie

        Which has now produced this lovely notice above all of my pages:
        ‘Warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, ‘add_our_scripts’ was given in ROOT/wp-includes/plugin.php on line 395′

        • http://kav.in kavin

          Well, it looks like you tried to follow two articles here – CSS menu and superfish menu. :)

          Make sure the function add_our_scripts exists(usually in functions.php). Probably a case of Case sensitivity(Uppercase/lowercase/capitalize). add_Our_Scripts, Add_our_scripts and add_our_scripts – All are considered differently. And create the function if it doesn’t exist.

    • http://www.soniei.com Soniei

      I had the same problem until I changed two lines:

      ‘main-menu’ => ‘Main Navigation’,
      ‘another-menu’ => ‘Another Navigation’

      I used single quotes instead of __( ) and it fixed my problem.

      • http://kav.in kavin

        Thanks soniei, Indeed there is an error. Here is how the code should have been –

        ‘main-menu’ => __(‘Main Navigation’),
        ‘another-menu’ => __(‘Another Navigation’)

        Article has been updated with corrections. Thanks a lot!

  • Vicky

    Great tutorial. Thanks!!
    There’s a fault in the CSS provided. The 3rd tier menu is not positioned on the same level with its link, but it is positioned on the top first link instead. Is there any quick fix to it?

    • http://kav.in kavin

      Works fine here. Can you show me a screenshot please? Any browser specificity?

    • http://kav.in kavin

      I verified this again, looks ok. Check with this Image.

  • http://www.lisa-noble.com Lisa

    Thank you sir! The CSS you provided has the drop down a little too far over to the right (at least on my menu) in IE7, but that’s a quick fix anyhow. Other than that your code is beautiful!

    • http://kav.in kavin

      Thanks.You’re welcome.

      On IE7 compatibility, may i please bother you for a screenshot? It appeared okay when i tested the code in WinXP SP2, so i would like to know what the problem looks like.

    • Justin Villocido

      Nice Tutorial… I have a problem with IE8 though and attaching the screenshot here. When the top level is hovered the pull down opened at the right… 

      • Kavin Gray

        Hi Justin, it looks like the sub menu list ( ul.sub-menu ) has css “left” value of 100%, so it appears below the next item than the one hovered. Verify the values and width if necessary. :)

  • http://www.wordpressstop.com Prasad

    Nice article.

    Please visit http://www.wordpressstop.com for to get lot of stuff regarding to WordPress.

    Keep Smiling

  • http://www.vibrancephoto.co.uk Matt Hawkins

    Thanks very much for this – It’s made my website much better and I’ve managed to dump a plugin and some JS in the process!

    Thanks :)

    • http://kav.in kavin

      You’re welcome, I’m glad i could be of assistance. :)

  • Russell

    I know it seems silly but my client wants the drop downs to work on IE6.
    the drop downs are appearing below and to the right, only on IE6.

    Do you know of anyway to fix this?

    Great write up BTW :)

    • http://kav.in kavin

      Hi Russell, many clients ask that. IE6 compatibility IMHO is not silly but rather shows our dedication as a designer. :)
      There is no way to get this menu working 100% in IE6 and earlier, unless with JS. With jQuery, you can do something like..

      jQuery('ul.dropdown li.dir').hover(function() {
         jQuery('ul.sub-menu:first', this)
            .css({
              visibility   :   'visible', // Set to visible,
               left          :   '0' // Parent li has position: relative.
         });
      }, function() {
         jQuery( 'ul.sub-menu', this)
              .css({ visibility : 'hidden' });      
      });
      

      This might need quite an amount of adjusting though. Please let me know if you come up with a viable solution. :)

  • http://www.camperauctions.co.uk Dave S

    Nice tutorial, thanks very much.
    Can I ask, what menu are you currently using on this site to get the transparency and feint background image?

    • http://kav.in kavin

      You’re welcome, Dave.
      Transparency is done by using color defined with rgba Ex.

      .sub-menu {
      background: #003 /* Regular Hex */
      background: rgba(0, 0, 51, 0.4 ); /* rgba - rgb with alpha component. a, i.e the 0.4 is the opacity of the color */
      }

      RGBA allows you to achieve transparencies of the background color. Older browsers might not have support for rgba, so always have fallback hex defined.

      If you were asking about the menu and effects, It’s a wordpress + Javascript plugin i am currently developing. Thanks.

  • http://www.chrisboggs.com Chris Boggs

    Thank you, thank you, thank you! I have been learning Adobe Flex/MXML/Namespace stuff the last 2 months and totally gotten my head out of WordPress and had to add a puldownable menu to an existing live WP theme for a client in very little time and this article saved my bacon getting me back in the headspace of WordPress quickly! Thank. You. I appreciate your effort.

    Sincerely,

    Chris Boggs

    • http://kav.in kavin

      You’re welcome :)

  • Matt

    How can you mark the top level elements that have drop downs?

    • Anonymous

      Take a look – Here

    • Anonymous

      Take a look – Here

  • Wpstarlet

    Amazing article and so useful :)  

    You may wish to update this part of your post

    “If you encounter any problems, verify with the included (modified) functions.php and header.php below.
    {filelink=2}”As I understand a link should appear and lead the visitor to the files in question instead of displaying “filelink=2″.Thank you for this fabulous post!

    • Kavin Gray

      Thanks, I just saw that. I will fix it ASAP.

      You’re welcome.

  • A Sharper Razor

    Amazing article. Thanks so much for the code. Any idea why IE9 messes up the hover of just the top menu? Or is it just my site? http://www.asharperrazor.com if anyone wants to look. I’ll keep searching for a way to stop the “half gradient” hover.

    • Kavin Gray

      Sorry i usually reply to the comments on my mobile.. I recently moved to a different server which caused a lot of trouble in syncing the comments. I apologize for the late reply.

      I see that your menus are now up pretty good. Glad that you found the article useful. :)

  • Tung Phamthanh90

    Cool, but how i can add small arrow for menu that has child?

  • http://www.richard-dickinson.com richardpd

    Nice tutorial-thanks
    I want to add a nav menu item drop down link (in my customised 2011 WP theme),  to a page external to WordPress. Is this possible? If so how?

    • http://www.richard-dickinson.com richardpd

      Ok-I am answering my own question…I added the external link to my nav menu drop down via the custom menu using the custom link feature..very easily done-simples!
      I’ve used WP for ages but this is the first time I’ve used this-well done WordPress!
      Cheers all :-)

  • Rene

    Great tutorial ! Thanks for it.I only have an issue:  When I modify the functions.php  file, I can’t logon to the wp-admin. It does ask for user/pass but after I press the button  ’Log in’ it gives me a white page.
     
    If I don’t modify the functions.php file,  wp-admin works ok, and the menu on the front-end does work, but I can’t add new options to the menu.
     
    —————-
    My actual functions.php file is:<?php
    if ( function_exists(‘register_sidebars’) )
        register_sidebars(2);
    ?> 
    <eof>
    —————-
    How should modified functions.php file should look?
     
     
    Any help wil be strongly appriciated. Thanks!

    • kavin

      Hi Rene,
      Sure. Remove the eof tag at the end.
       
      I’ve put the code into this paste – http://pastebin.com/0Gd0bTHx. When you add the PHP code, make sure they are inside <?php and ?> tags.

  • Rene

    Hi Kev, I’m ReneThank you for your help with the functions.php file, I changed it like you said on your link and it worked … BUT … it only works when wp-admin is in english, and my wp is in WPLANG  ’es_ES’.
    This is the problem it gives me when I use the spanish version:I can’t add pages to the menu, because the timing-circle begins goes round and round and round and…. round… and never ends.
    And if I try to move an item in the menu it gives me error on  ”wp-admin/nav-menus.php” .
     
    Any suggestion ?
     
    Thanks again.

    • kavin

      Rene, sorry if i missed this early -  Try the modified snippet http://pastebin.com/0Gd0bTHx , with l10n function removed. Other than that, this snippet shouldn’t cause any more issues. :)

      • Rene

        Hi Kavin….  Sorry, what does l10n mean???The script you send me is the same I have on my website right now but it gives me problem when I use wp-lang in spanish,  works ok when it’s in english.Thanks 

  • vine

    Thank you – works well in a wordpress website I have created.  There are lots of dropdown plugins out there but they all have their foibles.  would be interested if anyone has used an IE6 fix for usability sake.

  • DanielleMeszaros

    Thank you , you are way past awesome! Couldn’t figure out for the life of me how to get the menu to drop!!!!!! 

  • Adam

    You rock.

  • alisaleem252

    Thank You so much. You are the best

  • http://www.boholwebdesign.com/ Phil Web Design

    Wow this worked like a charm…thanks great tutorial!

  • inao

    Estupendo, despues de mucho buscar es lo que me dio la soliciión. Muchas gracias. 

  • ajay

    hey kavin, wanted to congratulate you for this great tutorial. been spending days on the web to find something simple and i must say this is “the” one. I seem to be encountering some problems though with integrating the css to my style.css. I get as far as the second to last step but it seem once i’ve finally added the css, nothing changes? Any idea?
    Thanx and once again well done for the great work

  • Mike

    Hi Just to say thanks for the code. The WordPress site isn’t clear on how to set up the CSS so this made sense of it all.
    I do have one issue thought which I’ve been going round in circles to cure.
    I’ve put a ‘hover’ border round the menu items, but the dropdown page items have a double border round them? I presume it’s something to do with actioning of both UL and LI, but having tried to play around with the CSS I don’t seem to be able to cure it?
    KInd regards
    Mike

    • MIke

      I’ve worked out the CCS instruction ul.dropdown li:hover a is being used twice on the dropdown items on both the initial UL area and then the LI area.

  • Pratik

    Thanks 4 gvng dropdown code

  • Merijn

    Thanx a lot. works really well. just 1 thing.. How can I show active menu item with this? wordpress gives the active item .current_page_item as class.. But I dont get it styled so the active page menu item gets another style

  • njhawar

    i have no word to tnx you …………….

  • melld12

    great tut buddy! monster thx for it :)

  • Matt Keys

    The new menu systems in WP 3.0+ are a big step forward for wordpress, but I really wish they had implemented a start depth option so you could easily implement secondary menus or split menus. After trying many solutions around the web I finally decided to make my own varient of wp_nav_menu with this start_depth option.

    You use it like this:

    wp_nav_plus(array(‘theme_location’ => ‘primary_navigation’, ‘start_depth’ => 1));

    The above code would output a secondary navigation like you would want in a sidebar.

    check it out on my website if you are interested: https://mattkeys.me/products/wp-nav-plus/