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. S.K posted the following on February 7, 2008 at 10:03 am.

    Thanks a Zillion, Aaron!

    I’ll give it a whirl.

    Regards,

    S.K

    Reply to S.K
    1. Aaron posted the following on February 8, 2008 at 12:28 am.

      You’re welcome.

      Reply to Aaron
  2. 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
  3. 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
      1. Adam posted the following on March 12, 2008 at 3:19 pm.

        I am trying to use this on pages instead of posts, but am unable to get the subpages to drop down.
        I did change from wp_list_categories to wp_list_pages.
        here is my string <?php wp_list_pages('sort_column=post_title&sort_order=asc&style=list&children=true&hierarchical=true&title_li=0'); ?>

        Reply to Adam
  4. 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
  5. Sarah posted the following on April 14, 2008 at 8:19 am.

    i am trying to impliment this on my blog theme Oh So Very! and when I add the script, and check out my blog page it is completely blank. it seems that first script when added to the header.php file is the culprit….i know i am probably doing something wrong on my end…any help would be greatly appreciated! (i currently took the code off the blog page, so people have access to it)

    Reply to Sarah
    1. Sarah posted the following on April 14, 2008 at 10:56 am.

      ok i changed themes and figured out how to add the menu, but i can’t get it to be a dropdown menu. Also, how can i add both pages and categories to the same menu?> I apologize in advance if I sound lost with all of this….because i am :)

      Reply to Sarah
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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

Leave a reply

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