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.



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
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!
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!
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
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
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!
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.
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?
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…
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.
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);
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
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]–>
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.
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
Friday, May 16th, 2008 at 1:44 pm
Contact me by email: jeanbaptistejung AT yahoo DOT com
Friday, May 16th, 2008 at 1:59 pm
I send you an email but I think your email its wrong: Mail Delivery Subsystem
Friday, May 16th, 2008 at 3:53 pm
@ JBJ – Great write up and thanks for supporting it in the comments.
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!
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
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
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.
Friday, September 5th, 2008 at 9:55 am
wonderful,I now intend to do such a menu
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!
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…
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
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)
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.
Thursday, December 4th, 2008 at 3:23 am
thanks
Thursday, January 15th, 2009 at 10:16 pm
Not working in IE7. Please see site and advise.
http://www.pztalks.com/everyday
Monday, January 19th, 2009 at 6:34 am
indeed, not working in IE7 nor in Chrome. works great in FF though.
Wednesday, March 4th, 2009 at 9:56 am
thanks for the help
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?
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 “”;
}
?>
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!
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
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
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.
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
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
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
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
Trackbacks/Pingbacks
Leave A Comment
Become one of our
Featured Sites
Recent Trackbacks
Contributing Authors
Archives
Extras
WordPress Hacks Copyright © 2007-2009 | An Apricot Media Website
Template by StudioPress | Custom Design by Kyle Eslick and Blog Design Studio
RSS Feed Email RSS