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. 1

    Nice – can it be set to hover by changing ‘click’ references to ‘hover’?

    • 3

      Dan, have a look at this. Without giving the answer away on quite a simple solution, I say “why not take a stab at a few of these events?” :)

      Definitely not too hard to figure out at all. I’m a JS n00b, and still got it right away.

    • 4

      I tried the same, but it won’t work. Try to use mouseover or mouseenter. But since I am not good with this either, I can’t figure out a way to let it stay open when using the actual submenu but to close when moving somewhere else.

    • 5

      I couldn’t get it to work with changing the click event to hover. I’ll try the mouse enter event next.

  2. 10

    Good job, really awesome – clean and professioanal.

    I have a question – is it possible to close menu when user clicks somewhere outside of the menu area?

  3. 12

    Quick question, once integrated into my site the drop down does not move the rest of the page content down with it? Any ideas how to get this to work?

    • 13

      Hi – did you find a fix for this?

      I’m having the same issue with the content not being pushed down when the menu’s open.
      Also some of the elements below the nav menu are displaying on top of the open menu (slider/ buttons). See: http://bit.ly/YbBCsf

      Thanks

    • 14

      I wasn’t able to force the other elements down upon open, however I managed to get it to display over the top of them. If anyone else is wondering how to do this, you just need to add:


      z-index: 99999;

      to the following class:


      .cbp-hropen .cbp-hrsub {

    • 15

      Hey have you found a fix for this? It would be amazing to bump the whole content down. I was thinking of using the Js from the slide and push menu but know very little about JS. Any ideas anyone?

    • 16

      I haven’t I’m afraid.. I’ve stuck with adding z-index and allowing the menu to appear over the top of other content. I agree with you however, would be better if the content was pushed down

  4. 17

    A life saver! needed the same logic for a similar menu am coding fro scratch, with minor differences :) thank u :)

  5. 18

    may help for hover seems much easier if you just do this….

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

    • 21

      He’s saying you can replace the current script with this. It will achieve the affect but with hovering instead of clicking the links. I’ve not tested this on all browsers but it seems to work well in chrome.

    • 22

      Why should U change the original oop code? Isn’t easier to change this line from this
      $menuItems.on( 'click', open );
      to this
      $menuItems.on( 'mouseover', open );
      in order to get the mouse over effect? :)

  6. 23

    How do you make the navigation clickable when it doesn’t have any sub items?

    • 24

      I have the same restlessness, someone
      has accomplished, when you have sub items, that when clicking on the option to take me to the url indicated

      Thank you.

    • 26

      Got it:

      I found a way.

      For any menu item I want to use as a drop-down, I gave it a new class:
      <a href=”#” rel=”nofollow”>Dropdown Link</a>

      Then changed this line in the js:
      var b=$(“#cbp-hrmenu > ul > li”)
      … to …
      var b=$(“#cbp-hrmenu > ul > li.dropdown”)

      This turns all top-level links into direct links unless specifically marked for drop-down.

  7. 28

    Hi, love the drop down. Is it possible to make a menu item a link to another page though, rather than a drop down menu?

    • 29

      Hi, figured it out. Basically what I did was take out all the menu options that weren’t supposed to be a drop down and created another nav class that looked the exact same as the drop down menu one. Put that in a list with proper ul li properties and it’ll all line up and it’ll act like a normal menu!

    • 30

      Hi Michael,

      Could you please explain what you done exactly? The only solution I see is to create a whole new nav menu that sits to the side of this one, but in doing so we’d then need to change the ‘width: 100%;’ to a fixed width in pixels. Eg if we’re using a 940px width, give the main nav menu 900px, then the remaining 40px can be used for the additional nav menu (with a clickable link). This means the menu’s no longer responsive.

      I’m guessing you’ve found a more suitable way around this.. would be great if you could share your solution with us :)

      Cheers

  8. 31

    Hey guys. Thanks for this!

    I have a problem though. This does not seem to work in IE 7 or 8. Is there a fix I can apply to hack those browsers into a working state?

  9. 32

    Hello, how can i make it a vertical menu? and to reduce the drop box dimensions?

  10. 34

    Hi,
    I’m trying to add a jquery-ui effect to the dropdown, however, the .removeClass doesn’t seem to be working..
    Can anyone shed any light on this!?
    I’ve put together a to show the effect..

  11. 35

    Good job, i love it, but…

    …I have a question!

    when user clicks somewhere outside of the menu area it closes instantly… i want to leave it always open and i’m trying but cant afford that yet. someone want to help me please?!

    • 36

      Hi Pedro, just comment/remove this line:
      $body.off( ‘click’ ).on( ‘click’, close );
      Hope it helps. Cheers, ML

  12. 38

    im using it for an admin backoffice (for a school work) and when i do action on it it automatic close. i resolve it with some php, i turned off the jquery and do

    if (!isset($_SESSION[‘menu’]))
    $_SESSION[‘menu’]=1;

    if (isset($_GET[‘m’]))
    $_SESSION[‘menu’]=$_GET[‘m’];

    and then

    <a href=”principal.php?m=1″ rel=”nofollow”>Sobre Mim</a>

    Problem solved it will be always open when working on the content of the tab!!!

  13. 39

    Hello,

    First of all congratulations for this wonderful work and the valuable help you make the developer.

    I have a question about this wonderful menu that I would like to integrate into a website project.

    How to restrict the width of the menu placed in a wrapper 1200px?

    Alas, I am not come, can you help me?

    Thank you for all the resources and help.

    Very good job.

Comments are closed.