Horizontal Drop-Down Menu

A responsive horizontal drop-down menu inspired by the Microsoft.com menu.

Horizontal Drop-Down Menu

View demo Download source

This large horizontal drop-down menu simply shows the sub-menu when an item gets clicked. It’s inspired by the Microsoft.com drop-down menu. Some example media queries show how to adjust the menu for smaller screens.

The HTML

<nav id="cbp-hrmenu" class="cbp-hrmenu">
	<ul>
		<li>
			<a href="#">Products</a>
			<div class="cbp-hrsub">
				<div class="cbp-hrsub-inner"> 
					<div>
						<h4>Learning & Games</h4>
						<ul>
							<li><a href="#">Catch the Bullet</a></li>
							<li><a href="#">Snoopydoo</a></li>
							<!-- ... -->
						</ul>
					</div>
					<div>
						<h4>Utilities</h4>
						<ul>
							<li><a href="#">Gadget Finder</a></li>
							<li><a href="#">Green Tree Express</a></li>
							<li><a href="#">Green Tree Pro</a></li>
							<li><a href="#">Wobbler 3.0</a></li>
							<li><a href="#">Coolkid</a></li>
						</ul>
					</div>
					<div>
						<!-- ... -->
					</div>
				</div><!-- /cbp-hrsub-inner -->
			</div><!-- /cbp-hrsub -->
		</li>
		<li><!-- ... --></li>
		<li><!-- ... --></li>
		<!-- ... -->
	</ul>
</nav>

The CSS

.cbp-hrmenu {
	width: 100%;
	margin-top: 2em;
	border-bottom: 4px solid #47a3da;
}

/* general ul style */
.cbp-hrmenu ul {
	margin: 0;
	padding: 0;
	list-style-type: none;
}

/* first level ul style */
.cbp-hrmenu > ul,
.cbp-hrmenu .cbp-hrsub-inner {
	width: 90%;
	max-width: 70em;
	margin: 0 auto;
	padding: 0 1.875em;
}

.cbp-hrmenu > ul > li {
	display: inline-block;
}

.cbp-hrmenu > ul > li > a {
	font-weight: 700;
	padding: 1em 2em;
	color: #999;
	display: inline-block;
}

.cbp-hrmenu > ul > li > a:hover {
	color: #47a3da;
}

.cbp-hrmenu > ul > li.cbp-hropen a,
.cbp-hrmenu > ul > li.cbp-hropen > a:hover {
	color: #fff;
	background: #47a3da;
}

/* sub-menu */
.cbp-hrmenu .cbp-hrsub {
	display: none;
	position: absolute;
	background: #47a3da;
	width: 100%;
	left: 0;
}

.cbp-hropen .cbp-hrsub {
	display: block;
	padding-bottom: 3em;
}

.cbp-hrmenu .cbp-hrsub-inner > div {
	width: 33%;
	float: left;
	padding: 0 2em 0;
}

.cbp-hrmenu .cbp-hrsub-inner:before,
.cbp-hrmenu .cbp-hrsub-inner:after {
	content: " ";
	display: table;
}

.cbp-hrmenu .cbp-hrsub-inner:after {
	clear: both;
}

.cbp-hrmenu .cbp-hrsub-inner > div a {
	line-height: 2em;
}

.cbp-hrsub h4 {
	color: #afdefa;
	padding: 2em 0 0.6em;
	margin: 0;
	font-size: 160%;
	font-weight: 300;
}

/* Examples for media queries */

@media screen and (max-width: 52.75em) { 

	.cbp-hrmenu {
		font-size: 80%;
	}

}

@media screen and (max-width: 43em) { 

	.cbp-hrmenu {
		font-size: 120%;
		border: none;
	}

	.cbp-hrmenu > ul,
	.cbp-hrmenu .cbp-hrsub-inner {
		width: 100%;
		padding: 0;
	}

	.cbp-hrmenu .cbp-hrsub-inner {
		padding: 0 2em;
		font-size: 75%;
	}

	.cbp-hrmenu > ul > li {
		display: block;
		border-bottom: 4px solid #47a3da;
	}

	.cbp-hrmenu > ul > li > a { 
		display: block;
		padding: 1em 3em;
	}

	.cbp-hrmenu .cbp-hrsub { 
		position: relative;
	}

	.cbp-hrsub h4 {
		padding-top: 0.6em;
	}

}

@media screen and (max-width: 36em) { 
	.cbp-hrmenu .cbp-hrsub-inner > div {
		width: 100%;
		float: none;
		padding: 0 2em;
	}
}

The JavaScript

var cbpHorizontalMenu = (function() {

	var $listItems = $( '#cbp-hrmenu > ul > li' ),
		$menuItems = $listItems.children( 'a' ),
		$body = $( 'body' ),
		current = -1;

	function init() {
		$menuItems.on( 'click', open );
		$listItems.on( 'click', function( event ) { event.stopPropagation(); } );
	}

	function open( event ) {

		if( current !== -1 ) {
			$listItems.eq( current ).removeClass( 'cbp-hropen' );
		}

		var $item = $( event.currentTarget ).parent( 'li' ),
			idx = $item.index();

		if( current === idx ) {
			$item.removeClass( 'cbp-hropen' );
			current = -1;
		}
		else {
			$item.addClass( 'cbp-hropen' );
			current = idx;
			$body.off( 'click' ).on( 'click', close );
		}

		return false;

	}

	function close( event ) {
		$listItems.eq( current ).removeClass( 'cbp-hropen' );
		current = -1;
	}

	return { init : init };

})();

View demo Download source

Previous:
Next:

Tagged with:

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://www.codrops.com

Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 111

Comments are closed.
  1. 3

    All I get after installing everything is this error – ReferenceError: $ is not defined. It looks fine but no menus open up.

  2. 4

    What I don’t understand is the reason why you put, in the default.css file, the following definition:

    .icon-drop:before {
    […]
    text-indent: 8000px;
    […]
    }

    This seems to work in Chrome and Firefox, but not in Opera, Safari etc…
    Thanks for any explanations!
    Marco

  3. 5

    Would someone please share the code with me for closing the submenu when a submenu link is clicked? Thanks!

  4. 6

    Hi! Great job!

    Could anyone tell me how to keep one of the drop menus (the first one, for example) open “on page load” so I can make it the first presentation page?

    Thanks in advance.

    • 10

      Yes I would like to know how to do this too. I have switched click to mouseover however it needs more code than that like timeout..and how it mouses out.. I have a large subnav like the one shown on this demo. Please help!

  5. 13

    I just installed this beautiful jquery responsive horizontal menu bar for my empty webpage. The menubar has not been altered with any style or modification by me.

    Can anyone help me to:

    Keep the submenu to the width of my blue border (horizontal rule)–container width in Deskview. Currently when the submenu opens it expands and fills the whole width of the screen across. I would like it to show only within my container. (Even with the blue border line).

    When resizing the screen to mobile size, it looks great as it is (and thats how I want it exactly)–Like the mobile.–When you resize back to desk it has a different look (outside the container / blue boder-horiz rule)

    When styling this menu bar previously, It would seem that every change I would make in deskview to fix the problem, would create a new problem in mobileview. Mobileview of this menubar is PERFECT!–I need Desk to look like the mobile (even with the blue border line).

    Any help would be greatly appreciated. Thank you

    Here is the site / code:

    http://www.dothopper.com

  6. 15

    This is a beautiful menu btw, thanks very much Mary Lou.

    When I view my menu on Android and iphone, the menu is in the full open position showing all parent and children list items. My menu will be somewhat large, so this could be an issue. When I am styling it with my WYSIWIG editor, it looks like it will only show the Parents (no child items), but when I view it live on browser, it is open, exposing all parent and child items, and will not close.

    Is this the default? Am I doing something wrong? If so, is there a way to collapse the child items?

    Also, I found this code to ‘toggle’ a responsive menu:

    $(“.toggleMenu”).click(function(e) {
    e.preventDefault();
    $(“.nav”).toggle();
    });
    if (ww < 800) {
    $(".toggleMenu").css("display", "inline-block");
    $(".nav").hide();
    } else {

    }

    I have tried to use this (unsuccessfully) to ‘toggle’ the menu trying to create a ‘hamburger-style’ icon to then reveal Parent items.

    Is there any way to get this to work?

    Thanks very much for any help

  7. 16

    Hi,
    very good job, nice menu!
    i changed the onclick event to onmouseover
    is there a possibility to delay the mouseover event for lets say 0.5 secondes?
    thanks in advance

  8. 17

    I am using this for the main navigation on a site and it works great but i need the main tab and the sub nav activated for the page they are on. And they do, but can someone help me so that they can activate a different tab still from that page? You can see what I mean here: http://build4.edgemarketingdesign.com

  9. 18

    Hi, just FYI, for a tiny delay on mouse over use code below. I also added a delay while closing to make it less flickering. Oh, and you need to give each menu an id=”whatever”. Why I did this? I made the menu to open on hover, but sometimes you want to move the mouse to the top of the page without opening the menu. While moving you accidentally touch the menu and you get the huge menu div, you need than to move your mouse out of the div to hide the menu. This code adds a small delay ;-) ps, love this site, keep up the good work!

    var cbpHorizontalMenu = (function () {
    var $listItems = $(‘#cbp-hrmenu > ul > li’),
    $menuItems = $listItems.children(‘a’),
    $body = $(‘body’),
    current = -1;

    function init() {
    $menuItems.on(‘click’, open);
    $listItems.on(‘click’, function (event) { event.stopPropagation(); });
    }
    var timeoutId;

    $(‘#cbp-hrmenu > ul > li’).hover(function () {
    var id = $(this).attr(‘id’);
    if (!timeoutId) {
    timeoutId = window.setTimeout(function () {
    timeoutId = null;
    $(‘#’ + id).addClass(‘cbp-hropen’);
    }, 100);
    }
    },
    function () {
    var id = $(this).attr(‘id’);
    if (timeoutId) {
    window.clearTimeout(timeoutId);
    timeoutId = null;
    }
    else {
    timeoutId = window.setTimeout(function () {
    $(‘#’ + id).removeClass(‘cbp-hropen’);
    }, 100);
    timeoutId = null;
    }
    }
    );

    function open(event) {

    if (current !== -1) {
    $listItems.eq(current).removeClass(‘cbp-hropen’);
    }

    var $item = $(event.currentTarget).parent(‘li’),
    idx = $item.index();

    if (current === idx) {
    $item.removeClass(‘cbp-hropen’);
    current = -1;
    }
    else {
    $item.addClass(‘cbp-hropen’);
    current = idx;
    $body.off(‘click’).on(‘click’, close);
    }

    return false;

    }

    function close(event) {
    $listItems.eq(current).removeClass(‘cbp-hropen’);
    current = -1;
    }

    return { init: init };

    })();

    • 19

      Shame your code addons don’t work for me!

      I got the errors :

      SyntaxError: illegal character
      var $listItems = $(‘#cbp-hrmenu > ul > li’),
      societ...nu_3.js (ligne 12)
      ReferenceError: cbpHorizontalMenu is not defined
      cbpHorizontalMenu.init();

  10. 22

    Anyone have a fix for ie8? Seems that the demo works just fine, but nothing shows up on my site when I click an item. Potential conflict? Thanks.

    • 23

      Have you try to include the META TAG Validation after which is as following?




      —-

  11. 25

    Thanks for this!

    Did anyone successfully apply a slide transition to the menu? I’ve been trying jQuery’s .slideDown() but can’t get it working.

  12. 27

    Nice drop down menu. Is it possible to close menu when user clicks somewhere outside of the nav menu area?

    Many Thanks

  13. 28

    First of all, I love the menu! I’ve been looking for something like this for a while now. I wanted the menu to be static so that it always sits at the top of the page. I accomplished this with position:fixed in the CSS. I want the logo to also stay static at the top above the menu but when I set position:static, the image completely disappears. If I remove the position tag, the logo appears where I want it but it scrolls with the rest of the content. How can I keep the image on the page when scrolling?

    • 30

      I like to use animation fade or something use this code on mouseover


      $(‘#cbp-hrmenu > ul > li’).hover(
      function(){
      $(this).addClass(‘cbp-hropen’);
      },function(){
      $(this).removeClass(‘cbp-hropen’);
      }
      );

      but i like to know what is the best practice to use the animation on CSS or jquery?

  14. 31

    Hi, The menu works fine, but when I click an item sub ??menus are displayed below the pictures of the following section of the website.
    Thank you.

Comments are closed.