CodeinWP CodeinWP

Slide-Down Mega Drop-Down Menus with Ajax and jQuery

UPDATE 11/22/2010: I’ve completely revamped the code for these menus, making it a little cleaner and more efficient. Still works exactly the same way.

Slide-Down Mega Drop-Down Menus with AjaxWhile reading an article on CBC’s website, I noticed they have added what seem to be newly-designed mega drop-down menus that work in an interesting kind of way.

These looked like a cool and simple thing to reproduce, so I gave it a shot and came up with something that I think works pretty nicely.

It wasn’t as simple as I thought, and I don’t think my code is the greatest, so I’m open to suggestions. I think this could form the basis for a jQuery plugin but I’ve never created a jQuery plugin so I’m holding off on that for now.

Here’s the demo link if you want to view it before reading the description below:

Features of the Drop-Down Menus

Here are some characteristics of the CBC version, that I incorporated into mine:

  • The drop-down menus appear on click, rather than the usual hover
  • Instead of being positioned absolutely with z-index to overlay the content below, each menu slides down and pushes the rest of the content down with it
  • The content in each menu is loaded with Ajax
  • Once opened, the functionality is much like a tab switcher
  • There are no non-mega drop-downs mixed in, so they all work the same way, taking up the width of the entire page, like regular content
  • The selected menu’s link has an active state
  • The drop-down menu will not slide up unless the link of the currently-open menu is clicked; if a link of a non-open menu is clicked, the drop-down remains in place, and the content is updated accordingly
  • As an alternative to clicking the active menu item to slide up the drop-down, there’s a “close” button in the top right corner, much like you’d see in a lightbox or other modal window
  • Triangle indicators are present for each drop-down link; the active menu has an upward-pointing triangle indicating “slide me back up”
  • Animated loading graphic while content loads, a common Ajax-based solution
  • Works roughly the same in every browser from what I can tell

Bonus Features

In addition to those features, my version includes:

  • The URL changes using hash values, to enable deep linking (although it still has the problem of no back button which can be resolved with a plugin)
  • The up/down arrows are HTML entities
  • For my version, the up/down arrows and the “close” link are inserted dynamically with JavaScript; with JavaScript disabled those elements are useless, so the UI stays clean and the top links are still accessible (CBC’s top links are accessible with JS disabled, but the arrows stay in place)
  • Each menu is populated from an HTML file in a “dropdowns” directory; this is just a simple method to mimic CMS-driven drop-downs — the content can pretty much come from anywhere
  • You can easily add or remove menu items; just add an associated page in the “dropdowns” menu and link to the page (the link text should have the same name as the file minus the file exension)

Overview of the Code

The code isn’t too hard to figure out. I’m not going to go through it line by line, as in a customary tutorial, but I’ve added comments to the code that describe each major section. Although I have written articles on JavaScript and jQuery, for the most part I only stick to fundamental stuff, so I don’t claim to be a JavaScript expert. So if you have any suggestions for how to improve the code (make it more object-oriented?) I’ll be more than happy to consider and incorporate your thoughts.

Here’s a direct link to the live JS file if you want to take a peek. You can view the demo or download all the files using the buttons below.

And let me know if you think this style of mega menus is more or less usable than the traditional drop-downs that appear/disappear on mouse over.

102 Responses

  1. Brian Lang says:

    What’s the fallback for those without Javascript?

  2. davivid says:

    I think it would be much better to preload the menu content.

    • I don’t think so, because then you’re loading (in this case) 5 different mega menus that might never be opened. Remember, drop-downs are always optional, not mandatory content. Plus, the way I’ve designed it, the menu content populates the same div element. So to have all of them load would require they be inserted into non-existent DOM elements, or else have separate elements that show/hide (like a tab switcher).

      Also, since it’s sliding down, the wait time for the load is about the same as the slide, so the load time is pretty much irrelevant as long as your server load time is fine.

  3. I think this could be done with just CSS. No reason to bloat a dropdown menu with JS.

    • The way this works cannot be done with just CSS. This is not just a regular drop-down menu. Those have been done with CSS, and they work well. This is sort of a combination of mega drop-downs and a tab switcher, just to try something new.

      Personally, I don’t particularly think it’s all that great, I just thought it would be something I could try to code.

      • unscriptable says:

        I agree that JS is the better way here. I think it could be done with CSS3, though, under the following conditions:
        1) the content for the mega menus are pre-loaded,
        2) the document fragment part of the url (the “hash” part) is not being used by other parts of the page (e.g. no other links using the # sign)

        In most real-world applications, imho, these conditions would get in the way and JS would end up being necessary.

        Take a look at Snook’s latest diversion for a similar use of the document fragment via the :target pseudo-class:

        Nice writeup, Louis!

  4. Joost Kiens says:

    Like it, I will have to make something similar for a client’s project I’m working on. However they want actual content loaded instead of links. Not so sure what I think about that, feels kinda weird to me. But it will be fun to make.
    Will have to load the content asynchronously as well to avoid a duplicate content penalty.

    You might want to go ahead an try and make it into a plugin, it’s surprisingly easy, a lot of fun and great practice.

  5. Beben Koben says:

    hmmm … a simple code to create a mega drop down menu
    thanks for tutor master \m/

  6. nara says:

    It is very nice, I liked the dropdown in full width.

    I will try it..


  7. varadesigns says:

    It is nice.. I liked the drop down item in full width

    I will try with the downloaded file

  8. yadi rosadi says:

    That’s Nice, thanks for sharing Louis :)

  9. joy budiman says:

    that’s really nice :) in terms of SEO, how do you think this one compares to the preloaded menu content?

    • I was thinking that the best way to ensure SEO is to create the page to use PHP query string values to display the menus. Those values would be found in the HREF for each link like this: “index.html?menu=tutorials”. Then the JS code could use that instead of the page name.

      The fallback would be to inject the menus using PHP depending on the query string value. If JavaScript is on, then the query string would never appear. If JavaScript is off, then the page is reloaded and the query string decides which menu is opened.

      I think I’ll eventually re-do it to have that feature, otherwise the content in the menus will not be accessible. The same concept could apply to a tab switcher, to make it more accessible.

  10. alidad Modjtabai says:

    hi, I have tested this drop menu slidedown and works great, but when i change the file name to .php extension isntead of html, is not showing inside of drop menu is showing blank. is this only works great under html files in dropdown folder!

    my php files that i saved in dropdwon folder is comes with jquery code is this mean they blocked to view it in drop menu!

    how can i solve this!


    • Hi, Alidad.

      In order for it to pick up PHP files, just go into the main JavaScript file and change the value for the variable “ext” to “.php” instead of “.html”. There are a number of variables you can change in there to suit your needs.

      • alidad Modjtabai says:

        i did that before i posted this comments, is still not showing, for some reason is that they do not carry .js line in php files. any idea why!

        would it be possible if i could send to you files and see if you be able to solve it. i really need ur help with this after i have spend few hours and still not getting it.


      • alidad Modjtabai says:


        hi, please take look at the site at

        and go demo and then press tabe number 4, I want to add those in your menu using php files. this is the problme i have that i could be able to solve it.

        I appreication if you could please test to see if you be able to solve and and let me know thanks.

        • Okay, I think I see the problem you’re having.

          For the menus to open the appropriate content, they get the info from the HREF value of each link. In your example, the HREF value is just “#” so that doesn’t help. You have to create it to insert the correct file names in each HREF, which will then be read by the JavaScript, and the correct content will be opened.

          For example, whatever names you have for the menus, you also have to have the same names for the files.

          Menus called “resources” and “tutorials” would require the files to be called “resources.php” and “tutorials.php”. Then, the HREF value for “tutorials” would have to be “tutorials.php” in order for it to get the right content.

          Hope that helps.

          • alidad Modjtabai says:


            Hi, thank you so much for your response, i also tried that and still not working, please take look the copy of hrf what i put two different way of hrf and still not showing. I showing blank.

            Any idea!

          • Alidad, you’re going to have to send a link to an actual working example that uses my code, otherwise I can’t help you any further.

  11. As noted at the top of the article, I’ve revamped the code for this. View the source to check it out. If you minify it, it will be only 16 lines compared to about 130 expanded and fully commented.

  12. alidad Modjtabai says:


    I finally solved the bigger part but still has blocked some where. I uploaded this files for you to see it, please take look at and click on first second tabs “resource”.

    As you can see that they couldn’t do anything for some reason that .js line may not read it.

    i have attached the zip for you to see the the code at
    You can replied me by private email that posted on your forms.

    I appreication your help.


  13. alidad Modjtabai says:


    it is possible to have auto height instead of puting height number in css! if so where do i need to change that to make auto height.


    • Alidad,

      I tried auto height but it ruins the animation and the menus don’t expand properly. I’m not sure why that is, so I just used a regular height instead. The height is found in the CSS for #dropdown.

  14. Krecke says:

    Hi Louis, thanks for sharing this cool drop-down menu.
    When I open the file in Google’s Chrome, the content called by Ajax doesn’t appear.

    With Firefox everything works nice.

    Any reason?

    See ya =)

    • Hey, Krecke.

      Are you talking about the demo page on my live site? Or are you talking about the files that you downloaded that you’re trying to view locally?

      If you’re trying to view them locally, I believe you have to run them on a local server like Apache in order for the Ajax calls to work. Although I don’t know why it would work in FF. Maybe try uploading to a live directory and see if it works then.

      If you’re talking about my own live demo, maybe you can tell me what version of Chrome, because it works fine for me in version 7.0x. Thanks.

  15. Jerome says:

    Hi Louis and IW’s readers !

    Thank you for this tutorial / script / plugin. I like it a lot.

    I’ve been thinking about implementing it into a WordPress template. Any idea or advice to do so ?

  16. This one is nice but can we have the same on hover effect and also without the sliding content i.e. using zindex or such.

  17. raybak says:

    I think it would look great with slight css modifications like adding a nice background image for every drop down box.Imagine a sports or fashion website..

  18. Joe says:

    Is there an option to have this work on HOVER, rather than click?

  19. david says:

    I have move all the code into the $(document).ready(function () {}

        var addCloseLink = function () {
            $(dropDown, "#close-link").click(function () {
                $("#dropdown").slideUp(speed, function () {
                    $(">a").find("span").html(" ▼");
                    document.location.hash = "";
                return false;
  20. Do you have one for Joomla? My current menu is showing conflicts.

    • Darren says:

      Old comment I know but for I fixed this issue with mootools and jquery with

      <script src=""></script>
      <script type="text/javascript">var $j = jQuery.noConflict();</script>
      <script src="/templates/new/lib/js/general.js"></script>

      Then in general.js change all instances of $ to $j

  21. Jimmy says:

    Hi Louis, First of thanks for creating such a great menu.

    I added a background image in dropdown (#dropdown in stylesheet), here’s the code which I added :-

    background: transparent url(images/sports-2.jpg) repeat-x 0% 55%;

    And here’s the final code :-

    #dropdown {
    	margin: 0 auto;
    	border: solid 1px #ccc;
    	border-top: none;
    	display: none;
    	position: relative;
    	overflow: hidden;
    	height: 270px;
    	background: transparent url(images/background-2.jpg) repeat-x 0% 55%;

    Now it works fine and shows the background image but the problem is ajax loading image (loading.gif) is disappeared. I tried to tweak but I couldn’t figure out the reason. If remove the background image then loading.gif starts appearing but I want background image along with loading.gif so kindly tell me, is there a way show loading.gif before background image loads?

    • Hey, Jimmy.

      The problem is the specificity of the selector. You’re declaring the background image using the shorthand property, which is overriding the loading gif. Try the following:

      Change this line in the CSS:

      .loading {
      	background: transparent url(../images/loading.gif) no-repeat center center;

      To this:

      #dropdown.loading {
      	background: transparent url(../images/loading.gif) no-repeat center center;

      That should fix the problem. If not, then I’ll have to take a closer look and see if it’s something else.

  22. Kaielab says:


    Really Great work. I was looking for it ! How could I use it in Magento? Its seems that someone has managed to make it work with Magento :

  23. Claude says:

    Hi Louis,

    I really like your mega menu, very nice,

    I would like to use it in the footer of instead, but my problem is when the menu open we need to scroll the page to see the content.

    I try a few thing but no succes.

    I found something but i don’t know how to make the change.

     jQuery(function($) {
                var slide = false;
                var height = $('#footer_content').height();
                $('.footer_button').click(function() {
                    var docHeight = $(document).height();
                    var windowHeight = $(window).height();
                    var scrollPos = docHeight - windowHeight + height;
                    $('#footer_content').animate({ height: "toggle"}, 1000);
                    if(slide == false) {
                        if($.browser.opera) {
                            $('html').animate({scrollTop: scrollPos+'px'}, 1000);
                        } else {
                            $('html, body').animate({scrollTop: scrollPos+'px'}, 1000);
                        slide = true;
                    } else {
                        slide = false;

    I don’t know what do you think about this and if possible.

    Sorry for my poor english.


  24. Davidhog says:

    Very nice and works well….but

    We’ve started implementing in a development site (we’re using Zend Framework) and it all seems straightforward. However, the site detects locale and we add a locale identifier into the URL if the site is being viewed from outside the USA. So, in a US browser, the page URL might be something like If viewed in a UK browser the same page would have a URL of

    In a US browser, the megamenus work fine. In a UK browser, they open but we get a ZendController error where the data should be and Zend is objecting to the ‘gb’ in the URL. We’ve tried nearly everything, including stripping out the locale in the .htaccess but we still get the error.

    Any ideas why this should happen? I wondered about the ‘same domain’ issue but I don’t think it’s that.

    • David, I can’t say for sure what your problem is without seeing an example. Can you send a demo?

      But based on your description, it doesn’t sound like a problem with the menus, but something with the way the site is programmed. It could be something to do with the hash value changing in the URL, but again, I’d have to see an example, otherwise, I can only guess.

      • davidhog says:

        Hi Louis,

        Thanks for the very prompt reply. I’ll check with my colleagues about setting up a demo on Monday and will be in touch.

        We did make some minor changes in your code to prevent the ‘#’ value being shown in the URL (so the user is unaware of any change to the URL) and that works in the ‘US’ version. Could that be the issue on the ‘gb’ version?

        Again, thanks for the instant reply!



        • Davidhog says:

          Hi Louis,

          We’re trying an alternative approach. Our Zend index.php was using Zend_Router_Route_Regex to allocate the user request to the correct controller (of which there are loads). We feel that this has become too cumbersome so we’re implementing a better MVC methodology (still Zend) now and testing it with your code.

          It’s still a bit hit and miss but when (not if) we get it working, we’ll let you know.



          • Davidhog says:

            Hi Louis,

            Still no joy! We think we’ve narrowed it down though.

            On our front page, the mega menus work fine. As soon as we go to the next level (so, url =, the slide down operates but no data.

            It looks like the base URI is causing an issue in the javascript. In the case of our front page, the base URI is At the next level, it’s and the JS looks for the code to run in that directory, not the top level (so, it’s looking in example/corporate for a folder called dropdown instead of looking for it in example/).

            We tried setting base ref in the pages but that just gives us a base URI on our second level of example/corporate/example/corporate which is even worse!

            Any ideas that might help?



          • Davidhog says:

            Hi Louis,

            Now working with multi-level URL’S.

            The problem was the context at the time of the dd.load() call. And the solution was blindingly simple. We just put a “../” + in front of the “dir” and it solved the problem!

            We could read baseURI and work out how many “../”‘s we need but since we know how many levels down our system will go with its URL’s, we’ll probably just stick “../../../../” into the dd.load() and the system will work.

            Many thanks for a great script!



  25. Claude says:

    Hi Louis,

    what do you think my question ?

    Because i really like your megamenu but i need to know if it’s possible or not.

    Sorry for the code that i place in your page without your recommendation.

    I didn’t see it the first time.


    • Hey, Claude. Sorry about that, I forgot that I didn’t answer your question. For some reason I remembered answering it and thought you may have contacted me via email or something. (I get too much email!)

      So, basically, I’m not entirely sure what you are trying to accomplish. From my understanding, you just want the content to push the container to hold everything, or else to scroll the container. That should not require any extra script at all, you should just be able to add “overflow: auto” to the containing element, and that should do it.

      The best way for me to answer such a question would be if you put up a demo page and explained it using the page, or even right on the page. Then I can fiddle with it myself and fix it so it works for you.

  26. Jake says:

    Why it does not work in google chrome?

    • Davidhog says:

      Hi Jake,

      We have it working in Chrome, Safari, IE & Firefox. Don’t think we had to make any special browser provision either.

      What problem are you getting?



      • Jake says:

        I downloaded the code and when I tried it on local it does not work on Chrome. But in Firefox, IE, Safari, etc. it works.



    • Yeah, it should work fine in Chrome. The only thing I can think of is that you’re on the Chrome Dev build, which has had some issues. If you are, try it in Chrome Canary or Chrome stable, which should be fine.

      • Nemanja says:

        Im using the regular chrome version and it still not works but in firefox works like a charm! I cant figure out whats the problem. Help! Any suggestions?


  27. Trigger says:


    as I can load the first menu automatically after the side was loaded?


  28. Alicia Keys says:

    I love this and implemented it on one of my websites a few years ago. Is there a particular reason you opted for the menu to appear on click rather than hover? Great work! :)

  29. Stacy Kvernmo says:

    I am going to try to incorporate this into my WordPress theme. I’m nervous.

    • Stacy Kvernmo says:

      um…. maybe not. the html menu pages are throwing me off and I dont know php well enough to find a work around for the dynamic WordPress menus. Anyone else have any luck with this?

      • Shadid says:

        You need to edit “general.js”. There, you can modify the main settings and specify the directory where your menu files are. In your case : change it to wp-content/themes/{themename}. Hope it will be helpful.

  30. Shadid says:

    Many thanks

  31. evlj says:

    Hi, is it possible to do the effect every time i press the button, instead of doing “refresh” i would like to have a “closing” panel, than opening it again on different links… Is it possible to do? Thanks in advance!

  32. JOKERz says:

    is it possible to use direct menu structure without loading external file menu?
    i mean i don’t need to load lot of menu, thats way i want to put it directly.

    • You’d have to alter the menus slightly. First, you’d disable the part of the JS that loads the files via Ajax (that’s the part that starts with “dd.load”. Then you’d have to take the separate files and put them into the HTML, one after the other. Then, you’d have to write a script to replace the Ajax part so it will “show” or “hide” the chosen menu.

      I suppose I could create an alternate version that does that, but this one was mainly supposed to be used with Ajax.

      • JOKERz says:

        Lol…. sounds complicated
        Ok i’m gonna try it
        thanks for your advice

        hope to see your menu version without ajax soon :)

  33. jonah says:

    Hi Louis

    Great script!

    Have you developed a non ajax version yet?

    Thanks! Jonah

  34. tony says:

    Hi Louis

    I am having the same problems that Modjtabai was having in Nov ’10 but there is no solution to his problem posted.

    The menu was working fine up until I integrated it into my WordPress theme, now – after fixing an “uncaught TypeError: Property ‘$’ of object [object Window] is not a function” error (changing any reference from ‘$’ to ‘jQuery’ in the .js seems to fix it) – it is now sliding open, shows the loading graphic but then the “dropdown” div is blank/empty except for the close button.

    I am using the first version of the code (ver2 completely broke the menu) and have set the variable “ext” to “.php” instead of “.html”, the menus are named the same as the files, and I think I have correctly set up the variable “dir”.

    I’m not to hot on php and have been stabbing wildly in the dark at the code for a couple of hours to no avail.

    Do you have any ideas?

    This are the link to the main page:
    the menu code starts at line 88
    the link to general.js is at line 268

    Thanks for any insight you may have.

  35. ibraheem says:

    pls am trying to use this mega drop down but it showing blank on google chrome and opera.any help please

  36. VIVEK KUMAR says:

    Hi, Thanks for the Menu…
    We have implemented this mega drop down menu for one of the clients..

    This is working fine, great work
    Thanks again…

  37. fux says:

    hi luis,
    thanks for the great code.
    am trying to replace the html arrows by an image

    var downArrow = " ▼";

    i tried to replace by
    var downArrow = " ";

    but it s not working.

    or should i try to target css class in JS?


    • fux says:

      i tried to replace by

      var downArrow =" < span >  < img src='source.png' > " ;
    • It should work. Just make sure that the image reference is using the proper path. I believe the path needs to be relative to the HTML document, not relative to the JS. Try using an absolute path like this:

      <img src=’’>

      and see if that helps. In the meantime, if I get a chance, I’ll test it myself and post an answer back here.

  38. awesome demo, works great, implemented on my site without any major issues. Works great for what I needed it to do,
    check it out, this link is still in dev stages:

    I will eventually be

    Thanks for the code

    • Tim V.H. says:

      Hi Roberto,

      Any hints on how you incorporated into your magento site? I’m very interested in doing the same. I have a mega drop down menu already, but I can’t quite figure out how to push the content. Thank you!


  39. Neofarm says:


    I thank you for your menu, I look for it for a long time. I have nevertheless a problem, I wish(desire) on the place(square) of links into the trap sliding to post(show) a complete page there containing forms of the type(chap) contact for example. Yet(now), only the links display.

    What I would want to make is he(it) possible ?
    How may I make him(it) ?

    I thank you for your help(assistant).


    ( This message in summer writes in French then translates into Englishman(English people), I am sorry I do not speak English)

  40. Neofarm says:


    Je vous remercie pour votre menu, je cherche cela depuis longtemps. J’ai néanmoins un problème, je désire à la place de liens dans le panneau coulissant y afficher une page complète comportant des formulaires du type contact par exemple. Or, seul les liens s’affichent.

    Ce que je voudrais faire est-il possible ?
    Comment puis-je le faire ?

    Je vous remercie pour votre aide.

    (Traduction Française du message précédent)

    • I don’t think this menu can do what you want. I’m not sure I fully understand, but you cannot put a full page to display inside the menu. It sounds like an odd request, but if that’s what you’re saying, then no, you cannot display a full contact page inside the menu panel.

      If you mean that you want the links to lead to another page, well, you’re going to have to go through the JavaScript and find a way to reverse the fact that all the links are disabled by default. The links only trigger via JS, they will not link to their HREF value.

  41. neofarm says:

    Thank you for your answer

  42. Deena says:

    How did you give loading.gif animation. Its a static image right

  43. Chad says:

    Hello I currently am developing and branding Sharepoint 2013 sites. I’ve used this plugin to add a mega drop down nav on a sharepoint site. Now the issues at hand is that when viewing the sharepoint 2013 site in IE8 the dropdown content does not show up. It shows up in other browsers and even IE9 but not IE8.

    What could I look into to resolve this issue?

    • Chad says:

      correction, it doesnt work in any version of Internet Explorer

    • 1) Do you have a demo you can send me, that’s not working in IE? I’ll be glad to check it out for you.

      2) For me, it works in IE10. When you test my demo page, does it work in any version of IE?


  44. Alex says:

    Hi my problem is that after downloading the source files the menu cannot display while im offline. I would like to use the code offline when im not using internet

    • Alex says:

      The problem i have is with the browser compatibility while offline the menu cannot show on google chrome but it shows on IE8

    • It’s using Ajax to pull in the menus, so if I’m not mistaken, you have to be running a local web server to get it to work. Personally, I have Apache/PHP/MySQL installed locally and I use a program called XAMPP to manage those.

      I don’t think it will work without a real server, because of the Ajax interaction.

  45. Darren says:

    Hi Louis, how would I go about creating two instances of the menu on the same page..Looking to replicate these menus basically..

    Managed to get the main menu going, and I have no problems with styling it but adding a new menu for the top is proving a problem :/

    thanks in advance D

    • That’s a bit of a tough one. You’ll have to identify which menu is being clicked, then respond accordingly in the JavaScript. Right now, the code isn’t really set up to run that way, so it’s not easy. Basically, I’d have to restructure the code to be a little more modular/functional, but I don’t have the time right now.

      Hope you can figure it out. :)

  46. Raghu says:


    This looks cool. Any pointers on how I can change the background color on click of each of the menu items?

  47. Raghu says:

    Hi-sorted out the background color bit. Thanks for sharing!

  48. Alex says:

    Why not loaded in the demo files menu?

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).