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. Is this possible to have 2 child columns? I have many categories and I try to use this for mobile only. Thanks!

    • I’m looking for a solution to the same problem…

      Is there any way to add two child columns? Currently, the whole submenu column is stretched until the end of the page bottom!

      Also, the text is being wrapped… is there any way to increase the width of the menu??

      Thanks!

  2. okay, got it working now with wordpress menu. no need vor walker:

    ”,
    ‘container’ => ”,
    ‘echo’ => true,
    ‘fallback_cb’ => ‘wp_page_menu’,
    ‘items_wrap’ => ‘%3$s’,
    ‘depth’ => 2
    );

    wp_nav_menu( $defaults );

    ?>

    $(‘#dl-menu .sub-menu’).addClass(‘dl-submenu’).removeClass(‘sub-menu’);
    $(‘#dl-menu .dl-submenu’).prev().attr(‘href’, ‘#’);
    $(‘#dl-menu’).prepend(‘Open Menu’);

    • Thanks hans but I am not using wordpress. I need 2 child columns with this code:

      <a href=”?=home” rel=”nofollow”>Home </a>

      <a href=”?=submenu-1″ rel=”nofollow”>Submenu item 1 </a>
      <a href=”?=submenu-2″ rel=”nofollow”>Submenu item 2 </a>
      <a href=”?=submenu-3″ rel=”nofollow”>Submenu item 3 </a>
      <a href=”?=submenu-4″ rel=”nofollow”>Submenu item 4 </a>

    • I don’t understand what should the walker look like? Could you be more explicit about the code to note?

  3. Guess my code got stripped out. Let me try again!

    I’m having trouble with this in WordPress. I got it working, but it conflicts with one of my plugins (a slider plugin called Camera). When I comment out the link to https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js, the slider plugin works, but the menu does not. I tried dequeuing the default WP jquery file and calling the one from the google library/example (above), but the slider is still broken. Here is my site: http://historickeywestinns.com/new/mobile-homepage/. Anybody know what in jquery 1.9.1 could be conflicting with the slider plugin and what I should do to fix it? Or anybody know what in jquery 1.9.1 is required for this menu to work (that isn’t in jquery 1.10)?

    BTW, I have tried other slider plugins as well and none of them work when I have the link to the jquery from the example!

    • Update: I switched slider plugins (the Camera one was throwing errors like crazy), to Meta Slider, which does not throw errors. However, I am still having the same issue and wondering the same thing about Jquery 10.10.2 vs. 1.9.1

  4. Hello Mary Lou & everyone else,

    I am a beginner and stuck with what to do next.
    I uploaded the css and js folders,
    I added this:
    <link rel="stylesheet" type="text/css" href="<?php bloginfo('template_directory'); ?>/css/component.css" /> <script src="<?php bloginfo('template_directory'); ?>/js/modernizr.custom.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="<?php bloginfo('template_directory'); ?>/js/jquery.dlmenu.js"></script> <script> $(function() { $( '#dl-menu' ).dlmenu({ animationClasses : { classin : 'dl-animate-in-2', classout : 'dl-animate-out-2' } }); }); </script>

    to my header.

    and for testing I used the whole menu HTML you provided.

    I tested it out and the menu button is visible but when I press it on an iPhone it doesn’t open.
    Nor does it open in a browser (Chrome).
    I checked fr errors and warnings ad this is the error that pops up:
    event.returnValue is deprecated. Please use the standard event.preventDefault() instead.

    If Miss Mary Lou can’t help, is there anyone else that can, please ?

    • This menu also adds top margin to my site…how can I remove this margin?
      I’ve already tried margin: 0 auto!important; but no luck..
      please help :/

    • Don’t worry about the Chrome “event.returnValue” issue. It’s not an error, only a warning.
      As for the reason for why your menu isn’t appearing, are you sure you’re using the source code?

    • Do you have the call out at the bottom of the page?

      $(function() {
      $( ‘#dl-menu’ ).dlmenu({
      animationClasses : { classin : ‘dl-animate-in-3’, classout : ‘dl-animate-out-3’ }
      });
      });

  5. I’ve posted a couple comments around the same time as Julia, but mine haven’t been accepted.
    Just wondering why…cause I really need help with this issue 😡

  6. I’m surprised no-one has mentioned yet that it won’t run unless you add the class “dl-trigger” to the button, which is not in your markup at the top of the tutorial!

    Still, awesome awesome work I love your tutorials!

    • Hi Jamie, we updated it afterwards and forgot to update the tutorial. Thanks for mentioning it. Cheers.

  7. I have a question: There are a way to close the menu when click outside it?

    (thanks for the code. I love the site, it’s became a important bookmark)

  8. Anyone know how to make the menu to show up above the button, going up instead of going down…

  9. Any way of keeping the top-most navigation static and just animating the dropdowns?
    Requirements:
    – Top Most menu items are always visible (like most website menu bars)
    – Submenus dropdown and are all fancy like normal
    – Submenus close when others open
    – Submenus aren’t full width, just wide enough to contain their children

    I have it almost working by adding the dl-menuopen class, hiding the button, and floating the top-most items left. But the dropdowns still cover the top items when clicked and the dropdowns are persistent (multiple can be open at once).

    Thanks all!

  10. Is anyone else having issues with the hovers in FF? They were working and as of last night, they arent anymore?? They still work in Chrome and Opera and IE … and as far as I know, FF didnt update without my consent ( was using FF 26 … just upgraded to FF 27 … same thing ). Anyone else having these issues??

    Heres the snippet of code that triggers the hover color –

    .no-touch .dl-menuwrapper li a:hover {
    background: rgba(255,248,213,0.1);
    }

  11. Hi,
    I got this close functionality working when clicking else where on the page. By default $body is assigned to body tag but most of sites which i tested this menu it didn’t work.
    So, this is what i did to get it work:
    var Modernizr = window.Modernizr, $body = $( ‘html’ );

    Hope someone finds this helpfull tip.

    Btw, this is awesom and nice looking menu. Thank you for that MJ.

    Best regards,
    Hakki

  12. Hi,
    what css changes one need to make if I’ve to extend the gap between menu initiative button and the real menu appear.

    I’ve made change on line 126

    .dl-menuwrapper .dl-menu {
    margin: 10px 0 0 0;

    to

    .dl-menuwrapper .dl-menu {
    margin: 40px 0 0 0;

    but when i navigate the animation comes odd from old 10px to 40px
    how to fix animation Y location as well.

  13. Can anyone help me? Is it possible to append the previous menu item text to “Back”. Something like “Back to ”

    Thanks

  14. It’s very awesome !
    Could you please tell me how can I change the button by an image or a text ? Thanks a lot.

  15. I tried implementing this on a new website but unfortunately it doesn’t seem to work with older android versions.
    We get a single bar and a single dropdown but any sub-menus don’t appear.
    It’s not the implementation as we experience the same when looking at your demo here using android phone – android 2.3.6.
    We really love this menu and would love to be able to use it in our site.
    If you can tell us any changes that might fix the problem I would really appreciate it.

  16. How to close the menu after option clicked?
    I try below, but doest work. Please help

    $(‘#menu1’).click(function () {
    $(‘#dl-menu’).closemenu();
    });

  17. What should I do with RESPONSIVE MULTI-LEVEL MENU for setting to wordpress?

  18. VERY NICE PLUGIN 🙂

    i’m a beginner of jquery plugins . can anyone help me ??

    i tried this of my html project ,
    my , problem is the back arrow are missing ?
    i copy all the components . but how come ?

    plss help 🙁

  19. I always watch for your blog and use your work where ever application, But with responsive menu i am facing problem. It works fine with FF, Chrome, Opera same but not on browser Mozilla/5.0(Linux; Android 4.2.2; A1-810 Build/JDQ39) AppleWbKit/534.30(KHTML, Like Gecko) Version/4.0 Safari/534.30

    I am using acer table and on default browser sub menus dont show up for some reason and i am finding it hard to fix it. Same problem happen with the actual example done by you.

    Same issue on Android similar browsers.

    • I have the same problem only in Android ;-( but works fine for me on iOS. It would be great if it works on all devices, now i have to find another solution, to difficult for me to fix it

  20. Issue when using this menu on android 2.2 and android 4.0 Parent menu show as usual but sub menus doesn’t work, It seems to hide behind the parent menu. No such issue on chrome. I have not tried this on Apple may be apple has similar issue.

    It would be wonderful to make it work on all devices.

    • I have the same problem, but in chrome. In firefox works perfekt 🙂 I didn’t tried yet on mobile phone. If anybody have a solution, please post it here.

  21. Hey Mary, I really like your menu. Am I allowed to use it (including the click here to open graphic) commercialy in one small project?

    Best regards,
    Jakob

  22. does not work with back ground images and will place its self behind div tags – which makes its un-usable. fit into the locked header container, just didn’t fully work. Witht he back ground image i was pushing it down for some reason that I personally could not figure out.

    • Yeah I think I’m having the same issue, I just pushes everything else out the way when it sits with others in the header container. Z-index isn’t playing nice either, probably beyond my skill-set.

  23. Wow! What a very cool menu this is. Many thanks for dev!
    One moment I’m having troubles with, does any one know how to make the menu close when I click a menu item that doesn’t have sub-menus?
    Any help will be kindly appreciated
    Thanks in advance

  24. Wow! What a very cool menu this is.
    One moment I’m having troubles with, does any one know how to make the menu close when I click a menu item that doesn’t have sub-menus?

  25. Just add last line in config to change back for back to "parent"
    _config : function() { this.open = false; this.$trigger = this.$el.children( '.dl-trigger' ); this.$menu = this.$el.children( 'ul.dl-menu' ); this.$menuitems = this.$menu.find( 'li:not(.dl-back)' ); this.$el.find( 'ul.dl-submenu' ).prepend( '<li class="dl-back"><a href="#">back</a></li>' ); this.$back = this.$menu.find( 'li.dl-back' ); $('li.dl-back a').each(function(index){$(this).append(' to '+$(this).parent().parent().parent().parent().parent().find('a:first').text());}); },

  26. I use Modernizr version 2.8.3, but the menu does not appear.
    With version 2.6.2 is ok.

    How can I fix?

  27. Great tutorial, the problem I’m having implementing this is when I try to put the nav button in a header with a search box next to it. I’m trying to work it in using the z-index but the dl-menuwrapper still pushes everything out. Has anyone managed to work this into a header with other divs alongside?

    Any tips would be greatly appreciated.

    Thanks

  28. Doesnt work with WordPress…
    i`ve put this in footer.php
    ————–

    $(function() {
    $( ‘#dl-menu’ ).dlmenu();
    });

    —————–

    error
    Uncaught TypeError: $ is not a function

    • Not the author’s fault. Your page hasn’t loaded jQuery or jQuery is aliased to a different character. Make sure you’re loading jQuery and loading it before initializing the plugin

  29. First off, this is such a great menu you have created and does exactly what I was looking for. Secondly, a beginner question, how do you change the colour of the boxes?

  30. menu looks cool but is not responsive to screen size. It would have been great if it looked like a normal top bar navigation on a desktop

  31. This menu is not working on any mobile device, ipad, samsung, iphone. can anyone explain plz?

    • I close menu on click with

      document.getElementById(‘dl-menu’).click()

      Bye

  32. Hi,

    very nice menu!

    What can i do if i had a really long submenu ( scrolling ).

    So i can scroll the menu 🙁

  33. I want this menu destroy and reset option added, I added the reset menu myself and it takes me to the start, means open the menu from the first level, even if I am from 2nd or any lower level. Then I tried trigger click of elements which can take me to the next level but that work but menu is closed automatically. Can you help me to resolve, actually I am adding new levels by ajax after initializing the menu, so if I don’t do reset menu newly added levels don’t work. I want this to work, and remain at the same level where menu was opened.

  34. Thanks, this is really cool menu. I have included this in my static HTML pages but I am getting an error “Uncaught TypeError: $(…).dlmenu is not a function”. Any idea why his problem has arised.

  35. How can I make it so clicking on one of the top level items(What you click to open up a submenu) takes you to an anchor point at the top of the page?

    I tried the following with no luck…

    <a href=”#top” rel=”nofollow”>Brady Haran</a>

    I’m not sure what else to try, I feel like that should work but it doesn’t. I have some very long menus that evolve scrolling down the page to read them all. It is frustrating to have to scroll back up to the top of the page every time I open up a new submenu.

    Thanks,

    Chris

  36. Question.

    I’m using a very simple menu with no sub menu’s and right now when viewing in mobile I click a link, but the menu doesn’t close. I’ve had a few friends test out my site and they all mention the menu should close when one of the links is clicked. It just seems natural.

    I’m not the best with jquery or javascript. I was curious what code do I need to add to the .js file and where in the code do I need to add it in order to close the menu when a link is clicked?

    Can anyone please tell me the code to achieve this? None of the previous solutions I saw in these replies has worked for me.

  37. Hey all,

    great plugin! Thanks for sharing!

    I have one problem with the size. In a normal browser, the button has the normal size. If I use a mobile device like an iphone, the button is really small and the menu entrys are small as well. I have to zoom in to use the menu.

    How do I change the size of the button and the menu? What css tags are responsible for that?

    Its on a dev environment with a pw, so I cannot show it. Hope you can say anything w/o seeing it. I use typo3 for the website.

    Thank you for you help, I appreciate that!

  38. It’s a very very nice menu… but as I can’t put anything in the space underneath it – i.e. where the menu will expand, it’s all a bit pointless.

    The top of a screen is the critical area that your customers are going to see – not much use if it is blank.

    Thanks for the effort though 🙂

    • HI JT, not sure if this applies to your own situation? I added a z-index of 2 to the .dl-menuwrapper class and that allowed the menu to open above the other content on the page reliably. It is indeed a very nice menu, thanks to tympanus for making it available.