Displaying WordPress categories in a horizontal dropdown menu.

Posted on Wednesday the 16th of January, 2008 at 2:05 pm in Asides, WordPress

One of my readers recently asked how I created my horizontal menu bar: the short answer is by mixing CSS and Javascript.

The first step is to get WordPress to display the menu as a hierarchical list without a title. <?php wp_list_categories('sort_column=name&sort_order=asc&style=list&children=true&hierarchical=true&title_li=0'); ?>

We then wrap this WordPress code in the following so we can style it.

  1. <div style="text-align:center;">
  2. <ul id="menu" style="padding:0; margin:0;">
  3. <?php wp_list_categories('sort_column=name&sort_order=asc&style=list&children=true&hierarchical=true&title_li=0'); ?>
  4. </ul>
  5. </div>

I added this to my header.php, but you can add it anywhere you want it to appear.

The CSS is fairly simple and you just need to add it to your theme’s style.css file.

  1. ul#menu {
  2. margin: 0;
  3. padding: 0;
  4. list-style: none;
  5. width: 100%;
  6. font-size:1.2em;
  7. }
  8. ul#menu li {
  9. float: left;
  10. padding: 0;
  11. margin: 0;
  12. border-right:solid 1px #fff;
  13. }
  14. ul#menu ul li {
  15. float: none;
  16. position: relative;
  17. border-bottom: 1px solid #7EAED7; /* fixes gap problem in IE */
  18. border-left: 1px solid #FFF;
  19. z-index:1000;
  20. }
  21. ul#menu li ul {
  22. margin: 0;
  23. padding: 0;
  24. display:none;
  25. list-style: none;
  26. position: absolute;
  27. background: #9CC;
  28. }
  29. ul#menu ul ul{
  30. margin-left: .2em;
  31. position: absolute;
  32. top: 0; /* if using borders, -1px to align top borders */
  33. left: 100%;
  34. }
  35. ul#menu * a:hover, ul#menu li a:active{
  36. background:#7EAED7 !important;
  37. color: #FFFFFF;
  38. }
  39. ul#menu li a:link,
  40. ul#menu li a:visited,
  41. ul#menu li a:hover,
  42. ul#menu li a:active{
  43. display: block;
  44. padding: .2em .3em;
  45. text-decoration: none;
  46. background: #5587B3;
  47. color: #FFFFFF;
  48. }
  49. ul#menu ul li a:link,
  50. ul#menu ul li a:visited,
  51. ul#menu ul li a:hover,
  52. ul#menu ul li a:active {
  53. width: 8em;
  54. }
  55. Use the following to copy and paste the code.

Of course you will need to change the colors and text sizes to ensure it blends with the rest of the theme.

Now the last step is the to make it work as a drop-down list on all browsers. This could be done in Firefox with a simple CSS declaration, but Internet Explorer doesn’t understand the :hover pseudo classes, so we mimic this in Javascript.

  1. <script type="text/javascript">
  2. /*<![CDATA[*/
  3. var mbA,mbT,mbTf,mbSf;
  4. var mbR = [];
  5. function mbSet(m) {
  6. if (document.getElementById&&document.createElement) {
  7. var m=document.getElementById(m);
  8. mbR[mbR.length] = m;
  9. var i;
  10. e=m.getElementsByTagName('a');
  11. if (!mbTf) mbTf=new Function('mbHT();');
  12. if (!mbSf) mbSf=new Function('mbS(this);');
  13. for (i=0;i<e.length;i++) {
  14. e[i].onmouseout=e[i].onblur=mbTf;
  15. e[i].onmouseover=e[i].onfocus=mbSf;
  16. }
  17. m=m.getElementsByTagName('ul');
  18. for (i=0;i<m.length;i++) {
  19. mbH(mbL(m[i]));
  20. }
  21. }}
  22. function mbHA() {
  23. if (mbA) {
  24. while (mbA) mbH(mbA);
  25. mbHE('block');
  26. }
  27. }
  28. function mbHT() {
  29. if (!mbT) mbT=setTimeout('mbHA();', 0);
  30. }
  31. function mbTC() {
  32. if (mbT) {
  33. clearTimeout(mbT);
  34. mbT=null;
  35. }
  36. }
  37. function mbS(m) {
  38. mbTC();
  39. if (mbA) while (mbA&&m!=mbA&&mbP(m)!=mbA) mbH(mbA);
  40. else mbHE('none');
  41. if (mbM(m)) {
  42. mbSH(m,'block');
  43. mbA=m;
  44. }
  45. }
  46. function mbH(m) {
  47. if (m==mbA) mbA=mbP(m);
  48. mbSH(m,'none');
  49. mbT=null;
  50. }
  51. function mbL(m) {
  52. while (m && m.tagName != 'A') m = m.previousSibling;
  53. return m;
  54. }
  55. function mbM(l) {
  56. while (l && l.tagName != 'UL') l = l.nextSibling;
  57. return l;
  58. }
  59. function mbP(m) {
  60. var p = m.parentNode.parentNode;
  61. if (p.tagName == 'UL') {
  62. var i = 0;
  63. while (i <mbR.length) {
  64. if (mbR[i] == p) return null;
  65. i++;
  66. }
  67. } else {
  68. return null;
  69. }
  70. return mbL(p);
  71. }
  72. function mbSH(m,v) {
  73. m.className=v;
  74. mbM(m).style.display=v;
  75. }
  76. function mbHE(v) {
  77. mbHEV(v,document.getElementsByTagName('select'));
  78. }
  79. function mbHEV(v,e) {
  80. for (var i=0;i<e.length;i++) e[i].style.display=v;
  81. }
  82. /*]]>*/
  83. </script>
  84. Use the following to copy and paste the code.

A couple notes on the previous code.

  1. To activate it, change your theme’s <body> tag to <body onload=”mbSet(’menu’);>
  2. It was not written by me, but I’ve been using it for a long time and don’t remember where I got it.
  3. It can occasionally create a JavaScript error, and I’ve intended to rewrite it for a long time, but it usually works fine.

Related posts

  1. Cecile posted the following on March 11, 2008 at 12:23 pm.

    Please I just don’t understand where in the wordpress files should I put the javascript that enables I.E to read the roll over..

    Do I make a file apart or should I insert it in the index.php or something ?

    Thanks for your reply :-)
    Cecile

    Reply to Cecile
    1. Aaron posted the following on March 11, 2008 at 12:59 pm.

      You insert into your header.php file before </head>.

      Reply to Aaron
  2. frerieke posted the following on March 12, 2008 at 6:45 am.

    Hi Aaron!

    great work

    can I use this method also to create a hor. menu of my pages???

    What should I change in the codes?

    thanks, Fre

    Reply to frerieke
    1. Aaron posted the following on March 12, 2008 at 8:54 am.

      If you want to use this method with pages, you should be able to basically change wp_list_categories to wp_list_pages.

      Reply to Aaron
  3. Dylan posted the following on March 21, 2008 at 3:10 am.

    I love the dropdown menu, however, it seems like the subcategories like to magically disappear when moused over. This happens on both my website and yours. Any suggestions to prevent this behavior? It almost seems like the problem is less apparent when using a smaller browser window, but that might not be the case. It does this both in Firefox and Safari (haven’t tested IE yet), and it is present in both though it doesn’t seem to happen as much in Safari.

    Also, just want to clear up where you mention changing the tag; it is missing a quote after the ending parenthesis which breaks the function. As a warning to others, if you copy and paste it, be sure to replace the weird angled single-quote things with a standard single quote. I missed this and it took me forever to catch (fortunately Firefox’s error console pointed it out).

    Reply to Dylan
    1. casey posted the following on July 18, 2008 at 1:41 pm.

      THANK YOU! I just spent 20 minutes trying to figure out what was wrong. Everything worked fine except the drop downs.

      In case anyone isn’t clear how to fix it, add a double quote to the end after the last parenthesis, retype the first double quote so it’s correctly formatted and retype the single quotes around menu.

      Reply to casey
    2. John posted the following on August 4, 2008 at 2:59 pm.

      Any chance you’ve gotten feedback on this? This is a great use of wp with dropdowns, but I too have noticed slightly erratic mouseover behavior on the menus– Safari, Firefox 3 on Mac, IE 6 on Windows XP.

      Thanks, though, Aaron, for the great dev! Great use of menus, and something I’ve been needing for a while.

      Reply to John
  4. Michael posted the following on June 18, 2008 at 8:44 am.

    cheers for this – just have to go in and mess about with it all. As my JavaScript skills are basically rubbish you’ve saved me laods of time.

    Reply to Michael
  5. Cole posted the following on June 24, 2008 at 10:33 am.

    This is what I was looking for. I’ve tried it on my localhost and it works well. Thanks :)

    Reply to Cole
  6. david posted the following on June 24, 2008 at 11:04 pm.

    Thanks for the code but I do have a question.

    You said the following:

    To activate it, change your theme??s tag to

    Where do we exactly go to change the tage to ??

    Reply to david
  7. Dheeraj SIngh posted the following on June 28, 2008 at 2:49 am.

    I implemented it but the dropdown thing is not working.Can someone advice me on what is wrong. my site is http://www.reviewmirchi.com

    Reply to Dheeraj SIngh
    1. casey posted the following on July 18, 2008 at 1:50 pm.

      It doesn’t look like you changed the body tag as mentioned in the original post.

      See the section at the end of the last bit of code in the post.

      See my other comment about how to correct the code.

      Reply to casey
  8. dizang posted the following on July 1, 2008 at 9:59 am.

    can you make a plugin for wp? thx..
    or where can i find a plugin.

    Reply to dizang
  9. Adam posted the following on August 8, 2008 at 8:23 pm.

    I just installed this but the drop down menus aren’t showing. Just the “top” categories. Any advice? thanks

    diysrc.com

    Reply to Adam
  10. valenki posted the following on August 16, 2008 at 3:01 pm.

    The drop-down menu may not work, because of the gap is not closed. Change tag to the following (as you see, with the closed gap):

    body onload=?mbSet(??menu??)”;

    and script will finally start working. Hurrey! )))

    Reply to valenki
  11. CodeKiller posted the following on August 26, 2008 at 9:09 am.

    Why not just use Suckerfish (an 11-line Javascript) instead of your 100-line script? It doesn’t throw errors and simply works, without extra markup and “classitis.”

    Reply to CodeKiller
    1. Aaron posted the following on August 30, 2008 at 6:19 pm.

      My code works on (theoretically) infinate levels of menus. The suckerfish requires a lot of work to get multiple levels as you can see inthis post.

      Each level has to be styled individually by hand which makes it close to worthless in a dynamic setting such as blog categories.

      If you need one level of dropdowns, then by all means, use suckerfish, but I found it didn’t work for what I needed it to do.

      Reply to Aaron
  12. Sam posted the following on September 30, 2008 at 12:16 pm.

    If I use this in my sidebar, how would I edit it so that the menus appear to the right of the category, instead of underneath it?

    Reply to Sam
  13. Kix the Geek posted the following on October 12, 2008 at 5:48 am.

    Hey, thanks a lot Aaron! This just spicened things up back at my blog. Even though I needed to edit a few codes to match my template and for it to be correctly placed, everything was worth it.

    Well done (for sharing this one).

    Reply to Kix the Geek
  14. Paul posted the following on October 27, 2008 at 3:10 am.

    It seems the subcategories like to magically disappear when moused over. This happens on both my website and yours. Any suggestions to prevent this behavior? It almost seems like the problem is less apparent when using a smaller browser window, but that might not be the case. It does this both in Firefox and Safari (haven??t tested IE yet), and it is present in both though it doesn??t seem to happen as much in Safari.

    Can you suggest a solution to this?

    Reply to Paul
    1. Aaron posted the following on October 28, 2008 at 12:57 pm.

      Paul » Right at the “seams” between links the effect can fail. The easiest way to fix it is to make sure they overlap a little bit in the CSS.

      Reply to Aaron
  15. Tasos posted the following on November 4, 2008 at 6:39 am.

    a fast solution is
    ul#menu li {
    float: left;
    padding: 0;
    margin: -.1em; *************it loses the borders but it works a bit better*******
    border-right:solid 1px #fff;
    }

    Reply to Tasos
  16. Henrique posted the following on December 6, 2008 at 4:22 pm.

    I tried everything and even with the correction on body tag and the sub-categories do not appear. Only the Main-category appears.

    http://www.fast-games.net

    Reply to Henrique
  17. David posted the following on January 26, 2009 at 11:28 am.

    I have installed this code and it all works GREAT! (To my surprise I did it right the first time!) I too noticed the problem with mousing over the sub-menu items. I applied the suggested fix and it does work better, but everything is crammed together. How can the code be modified to pad each entry with some spaces (3 maybe) to allow for some separation between the menu items? I think this would fix the problem (at least the look) of everything being so close together.

    Reply to David
  18. Gadzira posted the following on January 28, 2009 at 3:25 am.

    I am trying to make a list in my sidebar of Categories with a sub list of the posts in that category… somewhat like this:

    1. <a href="category_url" rel="nofollow">CATEGORY</a>
    2. <a href="post_url" rel="nofollow">POST</a>
    3. Use the following to copy and paste the code.

    Obviously I would like this to loop until it has played out all categories and posts within them.

    I am looking for tha code to make this happen in the same list format as I have custom styled menu tool in which i would like this code snippet to play out… so i need to di this WITHOUT A PLUGIN.

    Would really appreaciate any help!!

    Reply to Gadzira
  19. kevin posted the following on April 12, 2009 at 1:50 pm.

    didnt work on my site
    suckerfish is ok but not the greatest

    Reply to kevin
  20. Adam Winogrodzki posted the following on April 20, 2009 at 5:54 am.

    Didnt worked on mine too :(

    Reply to Adam Winogrodzki
  21. Povilas posted the following on May 9, 2009 at 11:58 am.

    In the bottom of article, there is written 3 steps to activate it. In first step there is one thing missing. right after body onload=?mbSet(??menu??); there is a need of “. So it must look something like body onload=?mbSet(??menu??);” to work :)

    Reply to Povilas
  22. Nitai posted the following on May 27, 2009 at 6:58 pm.

    Hi,
    I am just starting to build a site with wordpress and I would very much like to have a dropdown menu. However, it is not clear to me where to put the last javascript code you gave in this page; and if you look at my site the menu is stretching out from the side. How to position that? I have no any experience with php only html.

    Thanks in advance for your help.

    Reply to Nitai
  23. Julian posted the following on June 5, 2009 at 4:31 am.

    It doesn’t work for me. I’ve tried to copy the source code of your site too but the categories just don’t drop down…

    Reply to Julian
  24. Justin posted the following on June 14, 2009 at 7:27 am.

    i must be an idiot coz i couldn’t get it to work. probably too much of a n00b

    Reply to Justin
  25. Roman posted the following on August 6, 2009 at 5:03 am.

    Hello.
    Thanks, for your script.

    But how can I force it to work with IE6.

    Thanks

    Reply to Roman
  26. Harpreet Khera posted the following on August 27, 2009 at 7:35 am.

    I have categories and subcategories and i want subcat. to be displayed as drop down list with mouseover on parent category. Any help please..

    Reply to Harpreet Khera
  27. harry posted the following on September 10, 2009 at 5:27 pm.

    I want to try it too. thanks for sharing

    Reply to harry
  28. tech2connect posted the following on December 8, 2009 at 7:29 am.

    Nice tip to display my column in Column Thanks

    Reply to tech2connect
  29. WPExplorer posted the following on December 23, 2009 at 5:15 am.

    Simply amazing. Thank you very much!

    Reply to WPExplorer
  30. Nicole posted the following on January 20, 2010 at 4:38 pm.

    Thank you! This works beautifully. I was about to tell my client, “Nope, not possible”… ;)

    Reply to Nicole
  31. luxdesign28.ro posted the following on February 13, 2010 at 3:37 am.

    Don’t work on this website http://www.atlastur.ro. I use a vertical menu for categories…

    Reply to luxdesign28.ro
  32. Interior Decorating Schools posted the following on March 23, 2010 at 2:27 pm.

    Guys, for anyone that drop down not show up,maybe becau no post in your sub cat. try add this hide_empty=0

    wp_list_categories(’sort_column=name&sort_order=asc&style=list&children=true&hierarchical=true&title_li=0&hide_empty=0′);

    Reply to Interior Decorating Schools
  33. Montesquieu posted the following on April 16, 2010 at 1:18 pm.

    Hello, I’m using a code similar to yours. It works great but I have one thing I want to change and I can’t seem to find out how. I want to drop the uncategorized link in the Navbar. Everything else is great.

    Thank you for your help if you can or are willing, and at least thank you for your time.

    Reply to Montesquieu
  34. Johnny posted the following on July 19, 2010 at 10:15 am.

    Hi, thank you for writing on this subject. I have been looking for something like this and your blog helps me a lot to understand the topic better. Waiting for your next post.

    Reply to Johnny
  35. andyrio posted the following on September 2, 2010 at 8:30 am.

    I follow your step, and it work fine but, when i try to click my Categories list it’s lost..
    and i Q how to make separate Categories and work like pages. im new with wp

    Reply to andyrio

Leave a reply

:) :D :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: ;) :!: :?: :idea: :arrow: :| :mrgreen: