Responsive Multi-Level Menu

A responsive multi-level menu that shows its submenus in their own context, allowing for a space-saving presentation and usage.

Responsive Multi-Level Menu

Today we want to share an experimental drop-down menu with you. The main idea is to save space for menus that have a lot of content and sub-levels. Each sub-level in this menu will be shown in its own context, making the “parent” level disappear. This is done with subtle animations that are defined in separate animation classes. The menu is fluid so that it can be used easily in a responsive layout.

Please note: this only works as intended in browsers that support the respective CSS properties.

The structure of the menu contains an unordered list that can have an arbitrary number of sub-lists:

<div id="dl-menu" class="dl-menuwrapper">
	<button class="dl-trigger">Open Menu</button>
	<ul class="dl-menu">
		<li>
			<a href="#">Item 1</a>
			<ul class="dl-submenu">
				<li><a href="#">Sub-Item 1</a></li>
				<li><a href="#">Sub-Item 2</a></li>
				<li><a href="#">Sub-Item 3</a></li>
				<li>
					<a href="#">Sub-Item 4</a>
					<ul class="dl-submenu">
						<li><a href="#">Sub-Sub-Item 1</a></li>
						<li><a href="#">Sub-Sub-Item 2</a></li>
						<li><a href="#">Sub-Sub-Item 3</a></li>
					</ul>
				</li>
				<li><!-- ... --></li>
				<!-- ... -->
			</ul>
		</li>
		<li><!-- ... --></li>
		<li><!-- ... --></li>
		<!-- ... -->
	</ul>
</div><!-- /dl-menuwrapper -->

Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.

Animations are defined in animation classes:

.dl-menu.dl-animate-out-1 {
	animation: MenuAnimOut1 0.4s linear forwards;
}

@keyframes MenuAnimOut1 {
	50% {
		transform: translateZ(-250px) rotateY(30deg);
	}
	75% {
		transform: translateZ(-372.5px) rotateY(15deg);
		opacity: .5;
	}
	100% {
		transform: translateZ(-500px) rotateY(0deg);
		opacity: 0;
	}
}

.dl-menu.dl-animate-in-1 {
	animation: MenuAnimIn1 0.3s linear forwards;
}

@keyframes MenuAnimIn1 {
	0% {
		transform: translateZ(-500px) rotateY(0deg);
		opacity: 0;
	}
	20% {
		transform: translateZ(-250px) rotateY(30deg);
		opacity: 0.5;
	}
	100% {
		transform: translateZ(0px) rotateY(0deg);
		opacity: 1;
	}
}

And the plugin is called as following:

$( '#dl-menu' ).dlmenu({
	animationClasses : { classin : 'animation-class-name', classout : 'animation-class-name' }
});

We hope you like this little experiment and find it inspiring!

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

Fresh news, inspo, code demos, and UI animations—zero fluff, all quality. Make your Mondays and Thursdays creative!

Feedback 195

Comments are closed.
  1. From an intuitive usability standpoint, I think the 2nd demo is the only workable one, given that clicking into a submenu motions right and clicking back into the parent menu motions left.

    AWESOME. Mary Lou #ftw!

  2. How should I display these menus without using the “Open Button” triggered? I mean, the menu is already displayed in the page when pages’ loads and we don’t need to click the menu icon to show up the menu? Please help!

    • Try this:

      component.css:

      .dl-menuwrapper button {
      background: #ccc;
      border: none;
      /* width: 48px; */
      height: 45px;
      /* text-indent: -900em; */
      /* overflow: hidden; */
      position: relative;
      cursor: pointer;
      outline: none;
      }

      Also delete the “.dl-menuwrapper button:after” section.

      Add in script-section of index.html:

      $( ‘#dl-menu button’ ).on(‘mouseover’, function(){
      $(this).click();
      });

      $( ‘#dl-menu button’ ).on(‘mouseout’, function(){
      $(this).click();
      });

      Is that it?

  3. The demo doesn’t seem to be working right now (tested in the latest Chrome and FF)

    • Sorry about that! Updated and working now! Thanks for the feedback. Cheers, ML

  4. I can’t get this code works on my PC. Could someone please send me the files for the demo 1 only so I can study them?

    I mean the files without the unnecessary element for the demo 1 only.

    I will appreciate it so much.
    Thank you.

    Regards.

  5. Is there an easy way to make this a horizontal drop down menu on a desktop?

  6. Very nice, but unfortunately, without IE8 support it’s not very useful for websites that cater to the masses. IE8 is still a dominant browser, whether we like it or not. Here are my observations:

    Mostly functions in IE9+ except:
    1) No transition affects
    2) Back arrow shows as forward array

    On IE8 there are more problems:
    3) Main menu always shows and will not hide, regardless of clicking the “dl-trigger” button.
    4) Arrows do not display at all.

    #2 seems to be due to IE9 not supporting CSS rotate 180 degrees.
    #4 seems to be due to IE8 not supporting the custom font and the CSS a:not(:only-child)
    #1 is not too important, but #3 & #4 are show stoppers on IE8

  7. Thanks Mary Lou – I was looking for some form of navigation for a custom wordpress site that wasnt intrusive, and voila! you provided us with another amazing piece. Here it is in action http://www.stefanbadulescu.com. Thanks again!

    • Christi – I just read the comment last night and made instructions have a quasi-plugin on my site – meaning that you have to add something else to your functions.php – check this linkand hope it helps someone – you may have to make some modifications for however you are using it, as I did this for a custom theme I was building.

  8. If i have to trigger the open button (click event) from someother button elsewhere, how can it be done. please help, its urgent….

  9. I am using this menu on a temp page. It works great in all browsers. However, it seems on htc phones it doesnt work. The menu opens, i can click to the first submenu, however once there the back button doesnt work and the links to further submenus dont work. Works great on my iphone however with no issues. Thoughts?

  10. I thought this was great! until I tried it on my Samsung mobile phone (Galaxy Ace II).
    It worked nicely on my laptop at various viewport sizes and on my Nexus 7 tablet however.
    Any apple fanbois tried viewing it on an iphone?

  11. Love the dynamic animation… but its seems to not work in Firefox. The menu appears and you can click to go to a submenu but the moment the animation is finished the submenu disappears and you return to the first level and if you click again all you do is close the whole menu… :-Z

  12. Nice work buddy.,,

    But I want to make it to convert into a ajax website 🙂 in the place of just simple menu. So for this, I want to know that can we replace back button to a fixed top/bottom bar?

    If yes, than plz tell me how can I do it.

    Thnks n regards

  13. Anyone know whether the issue with Android phones has been addressed, or found out a workaround?

    Works perfectly in iOS, and this is easily the smartest, most professional and elegant solution I’ve come across for a mobile-perfect menu system. I’m planning to re-write it so that it behaves completely differently for tablets and PCs with a horizontal menu, and the sub-menus displayed together in a mega-menu type display. I hope this is going to be possible — mega-menus seem the way to go for widescreen devices, but they’re useless on mobile; this solution is perfect on mobile but seemingly overkill on a PC.

  14. Thanks for the tutorial. I was wondering if somebody could help me out a little. I have a single page site and this menu fixed to the top of the page. When you open the menu and click the links it takes you to different parts of the page. The issue I have is that when the link has been clicked the menu stays open. How would I edit the JavaScript to that the menu closed once the link in the menu was clicked? I only have a 5 item list with no sub menus so it’s a very simple menu.

    I guess that if the menu linked to different pages instead of different parts of just 1 page this wouldn’t be an issue.

    Any help is really appreciated.

    Many thanks,

    Matt

    (PS, site isn’t live yet.)

    • Use anchor in menu to identify the parts of your page.

      Search for
      self.options.onLinkClick( $item, event );

      and do something like that :

      var link = $item.find('a').attr('href'); var hash = link.substring(link.indexOf('#')+1); if( hash != "" ){ var elem = jQuery('div[data-anchor="'+hash+'"]'); autoScroll(elem); self._closeMenu(); }else{ self.options.onLinkClick( $item, event ); }

      autoScroll is a function to do the scroll to the specified part of the page with custom attribute data-anchor.

  15. Partial solution for IE:

    On .dl-menuwrapper .dl-menu , Change :
    translateY(10px);

    to

    translateY(-500px); /*or more depending on position of dl-menu*/

    Just to let it out of the screen.

    • IE 10 Fix
      Rather than translating the menu off the screen, hide the links using:

      .dl-menuwrapper .dl-menu a{display: none;
      }
      and make them appear using:

      .dl-menuwrapper .dl-menu.dl-menuopen a{display: block;
      }
      Enjoy.

  16. Thanks for this. I have a menu code that looks like this.

    {$MENU}

    I can add the first level ul class [dl-submenu] to the first ul above but cannot get the plugin to work for the children ul [dl-submenu] so only the first level is working. Can you please advise? I am not a programmer, just a web designer.

  17. To always show the menu without triggering the “Open Button”, just edit the first :
    <ul class="dl-menu dl-menuopen">
    and hide the Button via CSS

  18. I’m trying to use this in a jPanelMenu but it doesn’t work. Anybody tried ? Or know why the script ain’t executed and the menu stand still ?

    Seems like something’s catching the click or whatever. I’m pretty noob with javascript and have no other ressources to help me out :”( lol so much drama xD

  19. Hello!

    I find this very appealing menu. However, there is one point of criticism!

    The problem:

    One has the “Fashion” page filled with content as in the example, you can not select the menu this. You will be forwarded automatically to the submenus. This is extremely inconvenient, is not it?

    Is there a solution for this. For example, a split link in the same row? One link goes to the page “Fashion” and the second link (an arrow) on the submenu items.

    Thank you so much

    Harald

  20. I was wondering how to change the color, I see that when you download it each of the index pages load with a different color, but how would I go about customizing the menu? If you could just point me to the location of the code I should be able to take it from there.

    Thank You

  21. Nice so far, but the menu overlaps existing content and links underneath the menu are clickable…

  22. Is this possible to apply in wordpress dynamic nav menus? so that when I add new pages, it will automatically added to this responsive menu.

    • Sure it’s possible 🙂 I merged main and secondary navs into a single mobile nav panel. Here’s a code:
      <div id="dl-menu" class="dl-menuwrapper"> <?php if ( has_nav_menu( 'header-menu' ) ) { echo ('<ul class="dl-menu">'); wp_nav_menu( array( 'container' => '', 'theme_location' => 'header-menu', 'sort_column' => 'menu_order', 'fallback_cb' => 'default_menu', 'items_wrap' => '%3$s', 'depth' => '2', 'walker' => new Main_Nav_Menu )); wp_nav_menu( array( 'container' => '', 'theme_location' => 'header-secondary-menu', 'sort_column' => 'menu_order', 'fallback_cb' => 'default_menu', 'items_wrap' => '%3$s' )); ?> <?php echo ('</ul>'); } else { ?> <ul class="dl-menu"> <?php wp_list_pages( array('title_li' => '', sort_column => 'menu_order', 'items_wrap' => '%3$s' )); ?> </ul> <?php } ?> </div>

      The trick is to change default WP submenu classes. You can do this with additional JS code:

      $('#dl-menu .sub-menu').addClass('dl-submenu').removeClass('sub-menu'); $('#dl-menu .dl-submenu').prev().attr('href', '#'); $('#dl-menu .dl-submenu').prepend('<li class="dl-back"><a href="#">Back</a></li>'); $('#dl-menu > .dl-menu').prepend('<li class="header"> Navigation </li>');

      You can see how it works here.

  23. I tried to use the menu with a media-query “@media (max-width: 640px) { [component.css styles] }” but the menu doesn’t work in IE10 while using the query. Did anybody else have the same problem?

    • Mathis, I’m having the same issue. When I put the styles into a media query the functionality doesn’t work in ie10. The functionality does work in ie9 however which is strange. It works fine though in ie10 when it isn’t in a media query. Any thoughts?

  24. Hi Mary Lou,
    Every post you put on Tympanus is truly a Masterpiece; an enchanted phenomenal experience for all browser users! This post is no less.

    I have been trying all sorts of JavaScript-ing from doing a variety of toggles, toggle (Z-indices), show/hiding to testing and trying every CSS alternative I could put together, in enabling a website to have multiple triggers to different #mp-menu (nav’s). The only problem is that I am able to get another menu, but the the other menu pusher has a div in front of it, so the buttons cannot be clicked on the second mp-pusher menu. What do I do?

  25. This is awesome! Thanks!

    I was wondering if the menu can start open when the user enters the website, and when the user chose to close, it works open/close.

    Had anyone try this?

    • To let the menu to be open all the time, just search for this line:
      <ul class="dl-menu">
      and change it to
      <ul class="dl-menu dl-menuopen">

      For the open/close button, hide it with css

  26. Truly Awesome Work! Is there a way to setup menu to click outside of menu to close as well?

  27. Thanks Mary Lou, awesome job like always. I need to use two menus in one page. Made it work but there is a problem, when one menu is clicked and opened, and go to the second one, first menu won’t close. Any help with that? I don’t know how to call the closeMenu function when clicking another element on the page.

    • Never mind. I got it. I don’t know if it’s really right but it works. As follows:

      Added this line to the original Plugin just at the beginning.

      var pluginName = 'dlmenu';

      Initialize and close other menu when press dlmenu

      $(function() { var $menu1 = $( '#dl-menu-1' ).dlmenu(); var $menu2 = $('#dl-menu-2').dlmenu(); $menu1.mousedown(function() {$menu2.data('dlmenu').closeMenu()}); $menu2.mousedown(function() {$menu1.data('dlmenu').closeMenu()}); });

  28. What if the submenu li is also a link to a page? Then that page becomes unnavigable because every time you want to see it, you get that page’s submenu.

  29. Looks really nice, good UI solution in responsive webdesign, except for the fact that it’s not working so good in IE, even 10. When using IE10, move your mouse over de area where the submenu items appear. And click in this area, the menu goes wacko. Seems like IE10 already rendered the menu, except it’s invisible.

  30. Hi It is possible to solve the problem on IE10
    When using IE10, mouse over Menu area where the submenu items appear link items appear. Click in this area, the menu visible and hide

  31. The easiest way to let it work on IE is:

    add this ->
    z-index: 19; ( the number is your choise)

    to
    .dl-menuwrapper button

    i used it for a test markup
    http://www.movingpencil.de/demo
    you can test it with IE9 and IE10

    Hope this will be helpful 😉

    • i forget to add this :

      the cursor isnt changed by this but i am searching for a method like:
      cursor:default; to deactivate it for ie.

  32. This is truly one of the most elegant mobile menu solutions I’ve come across for complex multi-level menus – it’s perfect except for one thing… You really need to be able to have a link on a parent item that goes to a landing page rather than always linking to the sub-level menu. A convention that’s used in less-elegant solutions is to have the text in the menu link to the parent page, and an arrow icon to the right of the link text actually open the sub-menu. There’s a JQUERY plugin called Slicknav that uses this convention but your sliding nav panels are so beautiful. I know these are “demos” but if you ever decided to revisit them and add the parent level linking that would be AMAZING. BTW your UI work is inspirational 🙂

  33. Hello Mary Lou … i would like to thank you for this amazing menu, it helps me a lot with my project, redesigning the OpenCart admin area … you can see the results here 🙂 — http://opencartdemo.vagabondlabs.com/admin/ — username: admin password: demo —

    Ok, i am not a brilliant programmer and did not figure how can i make the drop down menu activates on MouseOver? … can you please help me with this.

    Thank you a million times for this menu, it really helped me a lot.

    Have a great and colorful day!
    Daniel

  34. Dont think the menu is working properly now. No functionality when clicked on the button. I think the javascript is not running for some reason. Anyone else having this issue?

  35. it is possible that the “sub” is hidden after a few seconds “tot”? how can I do? thank you so much! great menu!

  36. Awesome and thanks! I’d like to align the menu (the little square) at the top left of my window so I can keep the rest of my window for other elements. How can I position it there?

    Thanks!

  37. Great tutorial. Just curious if there is a way to make the menu open with the submenu active if you are on a page within that submenu? Thanks!

    • Great job!
      But I need this, too. Open the active submenulevel. Is there a solution for this?

  38. Hi Mary,

    It an awesome effect. I want to use this for one of my pages.
    How can I show the menu without button, but still have the same effect.

  39. Can anyone help with this problem.

    I need to open an external html file in an iframe on clicking on the main menu, as well as open the submenu.

    Tried solving it in the ‘jquery.dlmenu.js’ but couldn’t solve the problem. The submenu opens but the external does not load 🙁