make_dropdown Mouse and Mobile/Touch friendly jQuery drop down menu plugin

Hover-based drop down menus are a great solution when you’re short on space in your layouts, and are used all over the web. But what about mobile devices though? Everything goes out the door when you rely solely on hover effects.

There doesn’t seem to be many solutions out there that take care of this, so I’ve created a jQuery plugin called make_dropdown, which is basically a mobile (or touch)-friendly extension of SpiceBrain’s “jQuery Simple Drop-Down Menu”. By using this plugin, your menu will be activated both when hovered and clicked; but if a mobile, touch-based browser is detected it will only be activated when tapped, ensuring that your mobile users get a good experience.

I’m using it on this very site. You can get the code and learn more about it on github, or view a complete demo.

Saturday, October 1st, 2011, 1:30 am

|

32 Comments

  1. Alica says:

    This is exactly some thing I must do more research into, many thanks for the article.

    Reply  |  Link
  2. This is great and is just what was I was looking for (couldn’t find anything else like this when searching on google). Just one question…can it easily be adapted to a multi level dropdown?

    Reply  |  Link
    • sayeo87 says:

      Glad you find it useful, Neville. I think multilevel is doable but I might not have the time to implement it. If you know j query and would like to help out that would be great!

      Reply  |  Link
  3. I'm Sorry but it doesm't work on a android phone. says:

    I have installed and tried your plugin because it came up on top in google when searching for touch friendly dropdwon menu’s. For me it doesn’t seem to work on my android phone. When i tab the top link the drop down appears for a milli second and then it dissapears again. I’ve tried to do a event.preventDefault on the click action still no luck. I tried the demo menu which came inside the plugin folder.

    Which phones have you tested it on? And what should it do if it worked correctly?

    Thank You for the efforts though, this is not to be negative i’m just curious as to why or what i might be doing wrong

    Thanks piet

    Reply  |  Link
  4. Piet says:

    Hello Again,

    My bad i have didn’t read the instructions! After going to github and grabbed the latest version and following the instructions it seems to work. Thanks!!!

    Piet

    Reply  |  Link
  5. Kaitlyn says:

    I am trying to use this on a mobile friendly version of a site. The top level navigation are actually links as well as having subnav items. When I tap on the menu the dropdown works perfectly except that it also navigates to the page linked on the top level item. Any way to fix this?

    Reply  |  Link
    • sayeo87 says:

      Hey Kaitlyn, that’s a great question. I actually solved this (as you can tell by this page) by making the top level items not actual links, and setting the hover cursor to an arrow instead of a text cursor via CSS.

      If you make it clear that the item is actually a drop down menu, I think desktop users should be okay with it not linking anywhere.

      That said, if you want the behavior where top level links automatically become unclickable on mobile, I might consider adding that. Or if you have any other ideas…

      Reply  |  Link
      • Kaitlyn says:

        I would definitely need the top links to work on mobile as well. This site has been around for several years, I wouldn’t like to confuse users already familiar with the navigation system. On the Joomla sites we have, the navigation works perfectly on mobile. I’m not sure how they do it because I’m not really well versed with JQuery or Mootools. If you want an example, cffredco.org works well on both mobile and desktop.

        Reply  |  Link
      • Kaitlyn says:

        It looks as though this is what I’m looking for:

        http://www.cssplay.co.uk/menus/ipad-dropdown-single.html

        But thanks for a wonderful plugin!

        Reply  |  Link
        • sayeo87 says:

          Yeah, if its an existing site I can definitely see not wanting to confuse existing users. For what its worth, the menu in cffredco.org doesn’t work for me on my Android 2.3 phone, and the cssplay method doesn’t include the functionality where you can click again on an open menu to hide it (you have to click elsewhere on the screen instead)

          I’ll try to add the functionality of not opening top-level links in mobile tonight, just in case you decide to use my plugin again. =)

          Reply  |  Link
  6. Bob Ray says:

    The cffredco.org site menu doesn’t work on my Android phone (nor does your menu on this page).

    On cffredco, if I click on a top level menu item, I see the drop-down, but I go to the top-item link.

    On this page (on my phone), the menu is very attractive, but the blog drop-down appears for a second then disappears most of the time. If I click quickly enough, it will sometimes persist, but it will also appear when I tap elsewhere on the page later.

    I’m beginning to thing there’s no such thing as a decent drop-down menu for mobile. The only one I’ve found that works is at http://www.usa.philips.com/ and they’re loading 13 separate JS files for a page with almost no content.

    Reply  |  Link
    • sayeo87 says:

      Hey Bob, from what you describe I’m pretty sure your user agent is not recognized as mobile by my plugin. The checks were put in place some time ago so newer devices/browsers are probably not detected – I need to fix that or find a better way to check. Sorry for the inconvenience.

      Reply  |  Link
    • sayeo87 says:

      Hey Bob, I’ve just updated the detection code in the plugin to detect whether the current browser supports touch, rather than via brute force. Give it a try again.

      Reply  |  Link
  7. Kenny says:

    Hi,

    Thank you for this. I am having the same problem on my implementation whereby I need the top level link(s) to work as well. Any change of having it click once for the drop down and click twice to go to the linked page for the top level menu?

    Thanks!

    Reply  |  Link
    • sayeo87 says:

      Kenny: I won’t be adding any doube-click functionality – that’ll just be too confusing for the user. Would having the top-level link only actually link somewhere on non-touch devices, like what Kaitlyn suggested, work for you?

      Reply  |  Link
      • Kenny says:

        Hi and thanks for the quick reply.

        Having the top link ONLY link on not touch devices would be a temporary workaround. Basically the top link is also a page that can be chosen to go to in addition to the pages that are in the drop down.

        Any ideas?

        Thanks.

        Reply  |  Link
  8. Justin says:

    Just curious…using this plug-in, and it works great on desktop and tablet. Turns off top link, and mouseover or touch toggle works.

    However on mobile I want to turn it off(based on screen size, I got that part), so that the top level link actually takes us to the page and there’s no dropdown.

    I have a feeling it’s a matter of passing a parameter to $(‘#navlist > li’).make_dropdown(); or unbinding an event that the plug-in looks for. Didn’t see anything in the documentation though.

    Any ideas?

    Reply  |  Link
    • Justin says:

      Figured it out…may be useful to others:

      Altered the plug-in code with if statement to run if the screen is bigger than mobile.

      The first links are set to #, but then I rewrite at the mobile size to go to url of the page I need it to go to. Then write back to # if the screen is bigger.

      Seems to do it…dropdown on large screens and tablets, and link with no dropdown on mobile.

      I’ll put up some code when I get a free moment, on deadline right now.

      Reply  |  Link
  9. relicpro says:

    Thanks for the code. It’s much appreciated, as the other ones I’ve found that are mobile-friendly use js for the links, and that really doesn’t play nice to my SEO. I was wondering if it’s possible to insert a transition into the code, whether fading in or sliding down, but my understanding of JQuery syntax is pretty much nil (I’ve tried inserting code in different ways to no avail). Do you happen to know how I might get the drop down to transition in?

    Cheers.

    Reply  |  Link
  10. David says:

    I am grateful for your posting of this code. It’s exactly what I’m looking for.

    Will you kindly help me find out why the code of yours I’m trying to incorporate into my site isn’t working quite right? I find that it works on the desktop, but with my iPhone, when I load the page, the first time I work with a top menu item, I tap it once to open (that’s fine!), but I have to tap it twice to close it. After that, if I return to the same menu item, I’ll only have to tap it once to open and once to close (it toggles as I would expect)!

    I used my own CSS file (I didn’t use yours). Perhaps that’s the culprit?
    Note: Your is called “menubar” and mine is called “menu”, so I changed the term appropriately in my file in the JavaScript that appears right before the tag.

    My dropdown CSS is here: css/Emanuel_Blagonic_Harry_Roberts.css

    Here are some additional questions, and please forgive my ignorance, as this is unfamiliar territory for me:

    1. Do I need this file: js/make_dropdown.js ? What purpose does it serve? It’s included in the ZIP package, but not mentioned in the instructions.

    2.
    a) Do I need this file: http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js when I already have a link to this file : js/jquery-1.4.4.min.js ? Is the file you link to just a more up to date version of my file?

    b) Will it screw things up by having links to both versions?

    c) Can I put that link in my section of the document instead of right before the tag?

    3. Why does the functioning only seem to work when I call the script “make_dropdown.min.js” right before the “” tag, and not when I just link to the script in the section of my file?

    Thanks!

    Reply  |  Link
    • David says:

      Quick note: because of how markup is handled on this blog, some words in my post were eliminated.

      In the 3rd paragraph, I was referring to div menubar .
      In question #3, I was referring to the head section of the document vs the location of the ul.

      I hope that makes things clearer.

      Reply  |  Link
    • sayeo87 says:

      Hi David,

      Did you mean to post a full link to your CSS file? As it is, I don’t know how to access it as I don’t see any links…

      You don’t need the js/make_dropdown.js file. The just the uncompressed version of make_dropdown.min.js, which is the one you want.

      It is indeed a newer version of the same thing. The js/jquery-1.4.4.min.js file you already have is fine. No need for the version I specified. Still, if all else fails, no harm using a newer version. And you should only use one at a time. You can place this jQuery line anywhere before the line where you include js/make_dropdown.min.js

      I believe you need to include the make_dropdown.min.js, and make the “make_dropdown()” call, anywhere below where the HTML for your menu is. Perhaps I should make this more clear in the instructions. It is very common practice to actually put javascript include lines at the bottom of your page, as this allows other things to render first, giving the impression that the page is faster.

      Hope that helped!

      Reply  |  Link
  11. David says:

    Thanks for taking the time to answer my questions.

    May I ask a couple more?

    First, to find my files: the website is nondairycreamer dot com.
    http://www.nondairycreamer.com
    The CSS files are all in the top level folder called css.
    nondairycreamer.com/css/
    The js files are all in the top level folder called js.
    nondairycreamer.com/js/

    1. Why does the script make_dropdown.min.js work only when it is located in the html section of the document? I’ve never seen that behavior before, and I usually put all those files in the head section so I know where they are.

    2. Is it ok to have the jQuery line in the head section of the document? It seems to be ok there.

    3. Do you know why the script still isn’t working quite right? Here’s a recap of what I wrote above:
    I find that it works on the desktop (both with hover and clicking), but with my iPhone, when I load the page, the first time I tap a menu item, it opens fine, but I have to tap it twice to close it. After that, if I click the same menu item again, the toggling works — I’ll only have to tap it once to open and once to close!
    I am referencing a number of different files (CSS and js), so I wonder if there is some code in one of those files that is interfering with the functioning.

    Thanks,

    David

    Reply  |  Link
    • sayeo87 says:

      Figured it out! The issue was that for the “#menu li ul” CSS section, you were using “display: none;” instead of “visibility: hidden;”. The plugin explicitly looks for the CSS property “visibility: hidden” – that’s why the first time you click to close a menu, the plugin thinks it’s already closed and opens it instead. But from that point onwards, everything is in the correct state and works as should. So all you should need to do is change that one line of CSS.

      I’ll update the instructions to make this point more clear. Also, I’ve realized that putting both the script include and the call to make_dropdown() in HEAD works fine.

      Reply  |  Link
  12. David says:

    I am grateful! You really made my day! I have been putting this file together for about 4 weeks and now I feel it is complete.

    And I’m glad it was such a simple change, with a clear explanation of why it wasn’t working.
    (Yes, my CSS file was different and used some different descriptors). I’m glad the change is still compatible with everything else in my files.

    One thing puzzles me:

    Yes, I found that all the scripts could be put in the head section (!), but in order for your plugin to work, the jQuery script jquery.min.js needed to precede the other two scripts ( make_dropdown.min.js and the call to make_dropdown() ).

    Do you know why that is the case? I thought scripts could go anywhere and just need to be loaded into memory and then were activated when needed or in response to a user’s actions? Why does that script jquery.min.js have to appear first? If there is a reason for this, I think it would help (!) to make a note of that in your instructions.

    Cheers,

    David

    Reply  |  Link
  13. sayeo87 says:

    Glad it works!

    So javascript is actually loaded at the point the script is included. However, many scripts, such as mine, use callbacks such as “$(document).ready(…)” to make sure the main actions don’t get triggered until the page has fully loaded and the HTML elements it needs to act on are present.

    The jQuery line needs to be included before my script because my script is actually a jQuery plugin. Since the code is actually loaded at the time point of including, the jQuery code needs to already be loaded, otherwise my script will error out. (The browser actually hides those errors so in reality it just does nothing)

    jQuery is a very common javascript library used for simplifying the use of Javascript. The wikipedia page is a good intro if you’re interested to learn more. It might be a good idea to include the jQuery line before any 3rd party scripts you use, just in case they need to make use of it.

    Reply  |  Link
  14. David says:

    Thank you again for your explanations. I will read up a little more on how the jQuery works.

    One last question for now: For some reason, the plugin is not working properly for the deeper levels of the dropdown menus (see the links that appear below the Galleries link on the home page: nondairydreamer.com.

    The first time I tap these deeper level menu items below Galleries, they will open and close properly to reveal the additional choices. However, if i go to tap any of the same menu items below Galleries again, the menus disappear (the whole drop down closes up) and I can’t access the deeper links. Things will go return to normal functioning only when I reload my page.

    Question:
    Do you know how I modify the HTML or the CSS so that the deeper levels of the menus will respond to clicks or taps properly?

    Cheers,

    David

    Reply  |  Link
    • sayeo87 says:

      I never tested and explicitly supported nested drop downs, but I’ll see if I can do some testing later to see if its possible.

      Reply  |  Link
  15. David says:

    Thanks. If you do find a solutions, or if you know an easy way I could exclude the functioning of your script from just the mutiple-nested portion of my drop-down menu, will you let me know?

    Reply  |  Link
  16. Sam says:

    I was looking through Demo, u have used ‘#’ in main anchors. But in my case i have to use the link instead of ‘#’. But when i remove ‘#’ and add real url in href then your tool doesn’t work properly. I am looking for something that is used in your blog navigation menu. I opened this blog in my mobile and Blog Sub-Menu work perfectly fine for mobile and in browser as well. How u managed menu navigation in this blog page?

    Reply  |  Link
  17. Greg Weber says:

    LOVE the mobile friendly drop down! It works great! However, I’m trying to figure out how to make the dropdown part span the entire length of the whole menu, like this one does:
    http://ae.safeguardmontana.com/wp-content/themes/AEArchitect/healthcare.html (this is NOT your menu).

    Here IS your menu, and the dropdown sticks to the left edge of the parent element:
    http://ae.safeguardmontana.com/projects-2/healthcare/

    How do I style it to behave like the menu in the first link?

    Thanks!

    Greg

    Reply  |  Link
  18. Roslyn says:

    This post is very interesting, but is hard to find in search engine.

    I found it on 12 spot. You can reach google top ten easily
    using one useful wordpress plugin and increase targeted traffic many times.
    Just search in google for:
    Aemikimi’s Rank Plugin

    Reply  |  Link

Leave a Reply to Neville Palmer Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>