This guest post was written by Jean-Baptiste Jung, who maintains a blog (written in French) that covers WordPress. If you have webmaster or WordPress knowledge and are interested in writing a post for Hack WordPress, please contact us.

Tired of your old navigation? So, what about creating a Magazine-style drop-down menu?

I propose here a drop-down menu listing your pages and sub pages, including one last item to show up your categories directly in the menu.

HTML and PHP

We will start by using WordPress core functions in order to retrieve our pages and categories. Edit the header.php of your theme, and replace your old nav code by this one:

<ul id="nav" class="clearfloat">
<li><a href="<?php echo get_option('home'); ?>/" class="on">Home</a></li>
<?php wp_list_pages('title_li='); ?>
<li class="cat-item"><a href="#">Categories</a>
<ul class="children">
<?php wp_list_categories('orderby=name&title_li=');
$this_category = get_category($cat);
if (get_category_children($this_category->cat_ID) != "") {
echo "<ul>";
wp_list_categories('orderby=id&show_count=0&title_li=
&use_desc_for_title=1&child_of='.$this_category->cat_ID);
echo "</ul>";
}
?>
</ul>
</li>
</ul>

This code will make a list of all our pages and subpages, as well as a last list element named “Categories”. When an user will hover top level pages (in case of a page menu) or top level categories, we will show up the related sub pages/categories.

CSS

Even if the code is fully functional, our script needs a good CSS styling. This CSS, which was taken from Darren Hoyt’s free Mimbo Theme, is perfect for what we want to do.

#nav{
background:#222;
font-size:1.1em;
}
#nav, #nav ul {
list-style: none;
line-height: 1;
}
#nav a, #nav a:hover {
display: block;
text-decoration: none;
border:none;
}
#nav li {
float: left;
list-style:none;
border-right:1px solid #a9a9a9;
}
#nav a, #nav a:visited {
display:block;
font-weight:bold;
color: #f5f5f4;
padding:6px 12px;
}
#nav a:hover, #nav a:active, .current_page_item a, #home .on {
background:#000;
text-decoration:none
}
#nav li ul {
position: absolute;
left: -999em;
height: auto;
width: 174px;
border-bottom: 1px solid #a9a9a9;
}
#nav li li {
width: 172px;
border-top: 1px solid #a9a9a9;
border-right: 1px solid #a9a9a9;
border-left: 1px solid #a9a9a9;
background: #777;
}
#nav li li a, #nav li li a:visited {
font-weight:normal;
font-size:0.9em;
color:#FFF;
}
#nav li li a:hover, #nav li li a:active {
background:#000;
}
#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li.sfhover ul, #nav li li.sfhover ul, #nav li li li.sfhover ul {
left: auto;
}
a.main:hover {
background:none;
}

Javascript

Modern browsers (Safari, Firefox, Opera, and even Internet Explorer 7) will not have any problem with the :hover pseudo-class on li elements. But as we can easily guess it, the obsolete IE6 can’t deal with that.

In order to make our script compatible with IE6, we’ll need to charge this little unobtrusive Javascript code, in the head section our our HTML document, or even better, in a separate .js file.

<![CDATA[//><!--
sfHover = function() {
var sfEls = document.getElementById("nav").getElementsByTagName("LI");
for (var i=0; i<sfEls.length; i++) {
sfEls[i].onmouseover=function() {
this.className+=" sfhover";
}
sfEls[i].onmouseout=function() {
this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
//--><!]]>

Now, your new drop-down menu is ready and will give your blog a professional look.

Want automatic updates? Subscribe to our RSS feed or
Get Email Updates sent directly to your inbox!
Digg This | Stumble it | Add to Del.icio.us | | Print This

There Are 50 Responses So Far. »

  1. 1 Staicu Ionut
    Thursday, May 15th, 2008 at 6:51 am

    very nice tutorial. I wrote something like this yesterday on my blog. The difference is i don’t say anything about WP. Just lists :P

  2. 2 Enrique
    Thursday, May 15th, 2008 at 4:53 pm

    Hi there, How are you?
    I’m testing these in the theme of the site, but I don’t know where to put the unobtrusive script, would you so kind in telling me?

    We are a nonprofitable organization that helps people with low resources.

    There is something more, I’m getting problems with the css, in IE the footer and the bottom line from the part of the top site is showing problems, could you give me some little hand?

    thanks you very much!

  3. 3 jbj
    Friday, May 16th, 2008 at 12:21 am

    Hi Enrique, sure I can help you.
    For the unobstructive script: in the head section of your header.php file:
    <script type=”text/javascript”>
    //place the script from the article here
    </script>

    There’s obviously a problem in your css (I went to your website), I don’t have the required tools right now, but I’ll find how to fix it today, and i’ll post the resultat here for you.

    Good luck with your organization! :)

  4. 4 jbj
    Friday, May 16th, 2008 at 6:52 am

    Enrique, in order to fix the css problem on your site, just add padding-left:0; to #nav li ul :)

  5. 5 Enrique
    Friday, May 16th, 2008 at 7:24 am

    Incredible, you are a genius my friend, you fix it.

    A simple solution for a complicatred problem (for me haha)

    One more question, Im having a problem in firefox, the green menu appears in the top with some space in white and the other thing is that I added the script in the head section, but now I cant visualice the website in IE.

    Thanks man :)

  6. 6 jbj
    Friday, May 16th, 2008 at 9:38 am

    Thanks for your compliments, even if I’m far from being a Genius ;)

    You can fix the green bar problem by adding margin-top:-20px; to #topbar

    Have a nice day!

  7. 7 jbj
    Friday, May 16th, 2008 at 9:43 am

    For your ie problem, I guess it’s due to the quotes on the exemple I gave you to insert the javascript in the head section of your header.php file.
    You should replace it manually, i’m pretty sure it will solve the problem.

  8. 8 Enrique
    Friday, May 16th, 2008 at 10:09 am

    Is there any way you can see what I have done with the script? Because I deleted the quotes and but the menu doesn’t still appear.

    I tried to add the -20, but the menu in firefox disappeared.

    I don’t know if you can see it in IE, there is a problem with the line bottom of the top, its cuted? can you see it?

  9. 9 jbj
    Friday, May 16th, 2008 at 10:20 am

    There’s stillquotes in the javascript function, you should replace them all.
    I’m very surprised that the margin-top:-20px; to #topbar don’t work: I edited the file with FF addon web developper and it worked perfectly…

  10. 10 Enrique
    Friday, May 16th, 2008 at 10:25 am

    First off all thank you for you time man, very kind from your part.

    I will put the “margin-top:-20px” so you can see it in action. The problem appers in IE 7, IE 6 I dont know how it looks.

  11. 11 Enrique
    Friday, May 16th, 2008 at 10:27 am

    Wich ares the quotas?

    sfHover = function() {

    var sfEls = document.getElementById(”nav”).getElementsByTagName(”LI”);

    for (var i=0; i<sfEls.length; i++) {

    sfEls[i].onmouseover=function() {

    this.className+=” sfhover”;
    }

    sfEls[i].onmouseout=function() {

    this.className=this.className.replace(new RegExp(” sfhover\\b”), “”);
    }}}
    if (window.attachEvent) window.attachEvent(”onload”, sfHover);

  12. 12 jbj
    Friday, May 16th, 2008 at 10:59 am

    To solving the IE problem, place this on the head section of header.php:

    #topbar: margin-top:-20px;

    the quotes is this symbol: : you need to replace it manually.

    Good luck :)

  13. 13 Jean-Baptiste Jung
    Friday, May 16th, 2008 at 11:03 am

    Add this on the head section of header.php:
    <!–[if IE]>
    <style type=”text/css”>
    #topbar: margin-top:-20px;
    </style>
    <![endif]–>

  14. 14 Jean-Baptiste Jung
    Friday, May 16th, 2008 at 11:07 am

    Ah, just remembered that WP replaces two “-” by “–”, so the code above is invalid and won’t work. You need to use a conditional comment: there’s a good article here.

  15. 15 Enrique
    Friday, May 16th, 2008 at 11:33 am

    hahah sorry, I think you are going to kill me, but I dont understand these so good.

    1) I think I have delete all the quotes, am I right?
    (If this is ok, it stills not working)

    sfHover = function() {
    var sfEls = document.getElementById(nav).getElementsByTagName(LI);
    for (var i=0; i<sfEls.length; i++) {
    sfEls[i].onmouseover=function() {
    this.className+= sfhover;}
    sfEls[i].onmouseout=function() {
    this.className=this.className.replace(new RegExp(sfhover\\b),);}}}
    if (window.attachEvent) window.attachEvent(onload, sfHover);

    2) I think perhaps its my resolution, but when I see the website in IE, there is some space in with under the green footer, but I have a laptop and I see it ok there, how can I fix these problem?

    I hope these is the last, I don’t want to disturb you.

    Thank you very much, greetings from Argentine

  16. 16 jbj
    Friday, May 16th, 2008 at 1:44 pm

    Contact me by email: jeanbaptistejung AT yahoo DOT com :)

  17. 17 Enrique
    Friday, May 16th, 2008 at 1:59 pm

    I send you an email but I think your email its wrong: Mail Delivery Subsystem

  18. 18 Kyle Eslick
    Friday, May 16th, 2008 at 3:53 pm

    @ JBJ – Great write up and thanks for supporting it in the comments.

  19. 19 Jean-Baptiste Jung
    Saturday, May 17th, 2008 at 10:22 am

    @Enrique: Yeah you’re right! It’s yahoo DOT fr. Sorry for that! Write me up and we’ll fix the problem :)

    @Kyle: Thank, and no problem for support, I’m glad to help!

  20. 20 egi
    Thursday, July 17th, 2008 at 3:23 pm

    thanks for the great code Jean…
    but i want to ask you how to make the drop down category displaying the list child category.??like yours on top…
    blogging–>>wordpress tips

  21. 21 Edo
    Sunday, July 20th, 2008 at 10:12 pm

    Hi Jean,
    Very nice tutorial. I use it for my blog and works perfectly. Thanks.
    Is it possible to add some more codes, so the sub-categories pop up on the side when the pointer is above the main category? I think it will be neat.

    Thanks again :)

  22. 22 SEOAdsenseThemes.com
    Saturday, August 2nd, 2008 at 9:28 am

    Great article. Perhaps the most useful article when it comes to making dropdown categories list. I’ve bookmarked it and might implement a dropdown categories list in one of my WP themes in development.

  23. 23 freesky
    Friday, September 5th, 2008 at 9:55 am

    wonderful,I now intend to do such a menu

  24. 24 almanzarj
    Tuesday, October 7th, 2008 at 12:37 am

    hi guys this is a great guide! I have everything working except for IE6. I created a separate .js file and for some reason it does not work….any thoughts? is there a specific name or a directory this .js file should be in?

    any help would be great!

  25. 25 shawal
    Tuesday, October 21st, 2008 at 1:50 am

    Thanks for the tutorial….

    I got 1 question…

    In the dropdown menu, can i add subcategories in it…

  26. 26 Jake
    Sunday, October 26th, 2008 at 7:31 am

    Hi!

    I am having dramas with the menu. When I hover on a Top menu the sub menu will display but hidden under the smooth gallery photos. It there a CSS coding that will overcome this at all.

    Please follow this link for a screen shot at what I’m talking about.

    http://www.epsilonfoundation.com.au/menu.jpg

  27. 27 Iaan
    Tuesday, October 28th, 2008 at 6:40 pm

    Same problem as Shawal and Jake –
    Menu hidden behind Featured Content Slider & Want to disply another level of sub-pages. Please help!
    (www.twitter.com/iaanvn)

  28. 28 Iaan
    Tuesday, October 28th, 2008 at 7:15 pm

    @Jake Adding “z-index:999;” here:

    #nav li ul {
    position: absolute;
    left: -999em;
    height: auto;
    width: 174px;
    border-bottom: 1px solid #a9a9a9;
    z-index:999;
    }

    solved it for me.

  29. 29 Rizal
    Thursday, December 4th, 2008 at 3:23 am

    thanks

  30. 30 PZ
    Thursday, January 15th, 2009 at 10:16 pm

    Not working in IE7. Please see site and advise.

    http://www.pztalks.com/everyday

  31. 31 guyha
    Monday, January 19th, 2009 at 6:34 am

    indeed, not working in IE7 nor in Chrome. works great in FF though.

  32. 32 Kartik
    Wednesday, March 4th, 2009 at 9:56 am

    thanks for the help

  33. 33 Jim
    Friday, March 20th, 2009 at 8:30 am

    Hi,

    I want to use the dropdown categories on my blog and it’s working fine in Firefox 3, but its not working in IE.
    I’ve put this in header.php:

    GeekStuff

    cat_ID) != “”) {
    echo “”;
    wp_list_categories(’orderby=id&show_count=0&title_li=
    &use_desc_for_title=1&child_of=’.$this_category->cat_ID);
    echo “”;
    }
    ?>

    I also put the IE hack code in my menu.js file:

    sfHover = function() {
    var sfEls = document.getElementById(’nav’).getElementsByTagName(’LI’);
    for (var i=0; i<sfEls.length; i++) {
    sfEls[i].onmouseover=function() {
    this.className+=’ sfhover’;
    }
    sfEls[i].onmouseout=function() {
    this.className=this.className.replace(new RegExp(’ sfhover\\b’), ”);
    }
    }
    }
    if (window.attachEvent) window.attachEvent(”onload”, sfHover);

    But it’s not working in IE. Can you help me?

  34. 34 Jim
    Friday, March 20th, 2009 at 8:34 am

    previous code for header.php is not printed right to the blogpost.

    It should be:

    Categories

    cat_ID) != “”) {
    echo “”;
    wp_list_categories(’orderby=id&show_count=0&title_li=
    &use_desc_for_title=1&child_of=’.$this_category->cat_ID);
    echo “”;
    }
    ?>

  35. 35 Jim
    Friday, March 20th, 2009 at 8:36 am

    The code is still not shown correctly.
    If anyone has the solution for the dropdown menu problem in IE, please contact me!

  36. 36 fred
    Wednesday, April 8th, 2009 at 6:32 pm

    Is there anyway to use images instead of textbased links?
    I tried but it does not work properly. When the mouse makes a move inside the menu it dissapears. Kinda hard to explain.

    I want only the toplinks to be images, the submenus should be text.

    Any help would be great :D

  37. 37 Matt
    Saturday, April 11th, 2009 at 9:45 am

    I am new to css and I spent 2hrs trying to fix my code. It finally dawned on my that I had switched from firefox to IE, and when I went back to firefox everything was working exactly like it should have.

    I have written the below code into its own separate php file, and I then include that file at the top of my theme’s index.php file. This fixes all the problems dealing with IE. I would recommend everyone do this and hopefully we can take back the web from a company that thinks its above internet standards.

    Get your crappy ass browser off this site. If you want to view this site download or use one of the
    below supported web browsers below. I reccomend firefox, the others are still way better then IE.




    Download Firefox
    Download Opera
    Download Safari
    Download Chrome

  38. 38 Matt
    Saturday, April 11th, 2009 at 9:53 am

    darn, the code didn’t show up, oh well… basically it looks for IE via php and tells them to download better browsers then dies.

  39. 39 Rachna
    Friday, May 15th, 2009 at 8:15 am

    Hi jbj

    Kindly go here and check ‘About’ in the menu bar.
    http://theyoungindia.com/wordpress/

    Could you tell me why the last name in the drop down menu does not appear properly? I am unable to understand it. :(
    Would be happy if you could give me some time for this.

    Love,
    Rachna

  40. 40 Eddie Gear
    Thursday, June 11th, 2009 at 12:53 pm

    Hi there,

    This is a very interesting post. I’ve never really tried this option on my theme, but I might just give it a try.

    Cheers,
    Eddie Gear

  41. 41 Alex
    Monday, June 29th, 2009 at 3:00 pm

    How to make to have in drop down menu 2 lines with submeniu, because a have 20 submeniu and one colon looks to long

  42. 42 Alex
    Monday, June 29th, 2009 at 3:07 pm

    By you example I need to have:

    Categorie 1 Categorie 2 Categorie 3
    Apple | iPod/iPhone |MAC | GNU
    Scripts| Internet |Vista | XP

    2 line by 4 submenu



Leave A Comment