Overlay Effect Menu with jQuery

In this tutorial we are going to create a simple menu that will stand out once we hover over it by covering everything except the menu with a dark overlay. […]

In this tutorial we are going to create a simple menu that will stand out once we hover over it by covering everything except the menu with a dark overlay. The menu will stay white and a submenu area will expand. We will create this effect using jQuery.

So, let’s start!

The Markup

The HTML structure will consist of a main wrapper div for the menu which will contain the overlay and the unordered list for the menu. The menu itself will have a link and a div element as submenu in its list elements. Each of the submenu elements will contain lists for the columns of the submenu where each one will have a heading list element:

<div class="oe_wrapper">
	<div id="oe_overlay" class="oe_overlay"></div>
	<ul id="oe_menu" class="oe_menu">
		<li>
			<a href="">Collections</a>
			<div>
				<ul>
					<li class="oe_heading">
						Summer 2011
					</li>
					<li><a href="#">Milano</a></li>
					...
				</ul>
				<ul>
					...
				</ul>
				<ul>
					...
				</ul>
			</div>
		</li>
		<li>
			<a href="">Projects</a>
			<div style="left:-111px;">
				...
			</div>
		</li>
		<li>
			<a href="">Fragrances</a>
			<div style="left:-223px;">
				<ul class="oe_full">
					<li class="oe_heading">
						Fashion Fragrances
					</li>
					<li><a href="#">Deálure</a></li>
					<li><a href="#">Violet Woman</a></li>
					<li><a href="#">Deep Blue for Men</a></li>
					<li><a href="#">New York, New York</a></li>
					<li><a href="#">Illusion</a></li>
				</ul>
			</div>
		</li>
		<li><a href="">Events</a>
			<div style="left:-335px;">
				...
			</div>
		</li>
		<li><a href="">Stores</a>
			<div style="left:-447px;">
				...
			</div>
		</li>
	</ul>
</div>

The submenu divs will each have an inline style for the left position. As we will see, when we look at the style, we need to set this value since we want the submenu to be of absolute position, but within a relatively positioned container. So, in order to position all of the submenu divs at the beginning of the whole menu, we need to “pull” each div more to the left, hence we will have a negative left value for each div (decrementing 112px).

Let’s look at the style.

The CSS

Make sure, that you reset the styles first (we don’t want any browser-defined padding or margin for the list). We will start by the overlay for the body, which is a simple div with an initial opacity of 0:

.oe_overlay{
	background:#000;
	opacity:0;
	position:fixed;
	top:0px;
	left:0px;
	width:100%;
	height:100%;
}

The position will be set to fixed, since we want it to always stay on the top left corner filling the whole screen.
The main menu list will have the following style:

ul.oe_menu{
	list-style:none;
	position:relative;
	margin:30px 0px 0px 40px;
	width:560px;
	float:left;
	clear:both;
}

You might want to adapt its floatiness once you are planning to integrate this somewhere on your site. What is important, is the positioning of the list items:

ul.oe_menu > li{
	width:112px;
	height:101px;
	padding-bottom:2px;
	float:left;
	position:relative;
}

They will be positioned relatively so that we can have the absolutely positioned submenu elements.
The anchor of the top layer menu will have the following style, forming the box:

ul.oe_menu > li > a{
	display:block;
	background-color:#101010;
	color:#aaa;
	text-decoration:none;
	font-weight:bold;
	font-size:12px;
	width:90px;
	height:80px;
	padding:10px;
	margin:1px;
	text-shadow:0px 0px 1px #000;
	opacity:0.8;
}
ul.oe_menu > li > a:hover,
ul.oe_menu > li.selected > a{
	background:#fff;
	color:#101010;
	opacity:1.0;
}

In our JavaScript we will add the class “hovered” to the main ul, once we move with the mouse over the menu, so that we can change all the anchors to white:

.oe_wrapper ul.hovered > li > a{
	background:#fff;
	text-shadow:0px 0px 1px #FFF;
}

The submenu element will not be visible at the beginning, but only slide in when we hover over a top layer list element:

ul.oe_menu div{
	position:absolute;
	top:103px;
	left:1px;
	background:#fff;
	width:498px;
	height:180px;
	padding:30px;
	display:none;
}

The style for the links inside of the submenu lists:

ul.oe_menu div ul li a{
	text-decoration:none;
	color:#222;
	padding:2px 2px 2px 4px;
	margin:2px;
	display:block;
	font-size:12px;
}
ul.oe_menu div ul li a:hover{
	background:#000;
	color:#fff;
}

One of our submenu lists will be alone, so we want it to take all the space:

ul.oe_menu div ul.oe_full{
	width:100%;
}

And if it’s not alone, we want it to have a width of 150px, so that we can have 3 floating next to each other:

ul.oe_menu li ul{
	list-style:none;
	float:left;
	width: 150px;
	margin-right:10px;
}

And finally, we want the heading of the submenu list to stand out:

li.oe_heading{
	color:#aaa;
	font-size:16px;
	margin-bottom:10px;
	padding-bottom:6px;
	border-bottom:1px solid #ddd;
}

And that’s all the style! Let’s continue with the effects using jQuery.

The JavaScript

The main idea is to make an overlay appear that darkens everything on the page except the menu. We guarantee that the overlay stays under the menu because we placed it before the menu in the HTML structure. And the overlay stays on top of everything else because it all comes before in the HTML stucture. So, the z-indexes are in the wanted order. Consider that if you integrate this menu somewhere.

Let’s first cache some elements:

var $oe_menu		= $('#oe_menu');
var $oe_menu_items	= $oe_menu.children('li');
var $oe_overlay		= $('#oe_overlay');

When we hover any of the menu items, we will add the classes “slided” and “selected” to the item. The corresponding submenu div will get slided out and all the other ones will get hidden. We also give a very high z-index to the current submenu. When we move the mouse out, we will remove the class “selected”:

$oe_menu_items.bind('mouseenter',function(){
	var $this = $(this);
	$this.addClass('slided selected');
	$this.children('div').css('z-index','9999').stop(true,true).slideDown(200,function(){
		$oe_menu_items.not('.slided').children('div').hide();
		$this.removeClass('slided');
	});
}).bind('mouseleave',function(){
	var $this = $(this);
	$this.removeClass('selected').children('div').css('z-index','1');
});

The class “selected” is needed for the style, while the class “slided” is a helper class that let’s us identify which item is currently “in use”.

Now, we will take care of the overlay by defining what happens when we enter the whole menu wrapper. We will fade the overlay to an opacity of 0.6 and add the class “hovered” to the wrapper, so that the anchors stay white:

$oe_menu.bind('mouseenter',function(){
	var $this = $(this);
	$oe_overlay.stop(true,true).fadeTo(200, 0.6);
	$this.addClass('hovered');
}).bind('mouseleave',function(){
	var $this = $(this);
	$this.removeClass('hovered');
	$oe_overlay.stop(true,true).fadeTo(200, 0);
	$oe_menu_items.children('div').hide();
})

And that’s it! We hope you had fun with this tutorial and found it useful!

Tagged with:

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 up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 83

Comments are closed.
  1. excellent as always ! I did something like this some time ago, really nice to see another variation

    About usability, it could be nice if you use hoverIntent.js, so instead of immediately calling the onMouseOver function, it waits until the user’s mouse slows down enough before making the call.

    For example, you put your mouse over “Projects”, if you want to click the sub-item “wallpapers” you attemp to do a diagonal movement and this fire the hover state of “Fragance” sub-menu…

    It’s a detail, but I think it enhance your proyect/tutorial

    thanks for share as always and bring us new ideas
    good bye!

  2. Hello all, thanks for your feedback!
    @dlv thank you for the tip, that would indeed be a very good improvement.
    @Codeforest I was thinking about that, too and a slight delay was one of the solutions, but then it seems like it’s stagnating which was not so nice. Any suggestions?
    Cheers, ML

  3. sublime ! (in french 🙂 )
    All your tuts are incredible for inspiration.
    Thanks a lot for all.

  4. Looks absolutely gorgeous, Mary Lou, but I think I’d make a couple of small modifications:

    1. Insert the overlay div using JS, as it’s not really necessary in the markup without JS

    2. Modify the structure a little: use headings for the main section and .oe_heading because it makes more semantic sense (right now, structurally, the .oe_heading list element is just another list element, not a heading). Of course, you will probably need to package up each submenu within another div, but I don’t think that’s a HUGE problem.

    Once again, the menu looks beautiful – really nice work!

  5. this menu is great, so how can i change the fullscreen background image everytime i click a button in the menu?
    i would like to use this for a gallery.
    thanks for sharing…
    best wishes leo

  6. A great menu indeed, congrats Mary Lou.Trying to figure out what could be done with the background on mouse enter/out but i have no inspiration at the moment.
    But all in all this is highly usable as it is.Thanx for this.

  7. The menu title “Duke Fashion” is positioned at different points on the four browsers that I use, IE8, FF Chrome and Safai. They spread at different length so that you can’t see all the letters. The only one where you can see the full phrase is Chrome.
    Thanks, I love the idea.

  8. cool one . Please hav a look at this menu www2.goldmansachs.com/ , Cani use this for my next client project?

    Thanx in advance

  9. Javascript function replacement for if you want to use hoverIntent:

    $(function() {
    var $oe_menu = $(‘#oe_menu’);
    var $oe_menu_items = $oe_menu.children(‘li’);
    var $oe_overlay = $(‘#oe_overlay’);

    $oe_menu_items.hoverIntent( mouseenter_menu_items, mouseleave_menu_items )
    $oe_menu.hoverIntent( mouseenter_menu, mouseleave_menu )

    function mouseenter_menu_items () {
    var $this = $(this);
    $this.addClass(‘slided selected’);
    $this.children(‘div’).css(‘z-index’,’9999′).stop(true,true).slideDown(200,function(){
    $oe_menu_items.not(‘.slided’).children(‘div’).hide();
    $this.removeClass(‘slided’);
    });
    };

    function mouseleave_menu_items () {
    var $this = $(this);
    $this.removeClass(‘selected’).children(‘div’).css(‘z-index’,’1′);
    };

    function mouseenter_menu () {
    var $this = $(this);
    $oe_overlay.stop(true,true).fadeTo(200, 0.6);
    $this.addClass(‘hovered’);
    };

    function mouseleave_menu () {
    var $this = $(this);
    $this.removeClass(‘hovered’);
    $oe_overlay.stop(true,true).fadeTo(200, 0);
    $oe_menu_items.children(‘div’).hide();
    };

    });

  10. Nice tutorial, it’s easy ti implement and well documented. Keep up the good work \(^_~)/

  11. hi, i wanna use links or tabs for main content

    example, i put a link before text
    “welcome to the world of fashion” and the link appears but isn´t clickeable because Z index

    how can i use ?

  12. sorry if this is a basic question, but how would i allign this so it was in the center of the page. I’d like to try it centered at the top, but also in the middle.

  13. Yeah IE isn’t all too compatible. When are they going to smarten up?
    In any case, thank You bunch.

  14. The menu looks great and runs smooth as a babies bottom in FF.

    Too bad that (as @JAFD stated) it runs terribly in IE8.

  15. It is much easier to just set the opacity of the image to 50% against the black background when hovering the menus. Easy way of overlay effect.

  16. Cufon is the problem that makes it slow in IE8, but if you give every a class
    for cufon then IE8 will render it different

    now IE8 renders entire
    and that makes the lag.

  17. Mary Lou,

    Hi. I LOVE this template! I modified it to fit my current project. Question for you… how do I go about adding actual content to the links in the menu in the same format? I see they are all so not sure how to make a “plain white box” with more text on it. thanks so much!

  18. Hello Mary Lou
    I am Spanish and I am trying to put words with accents on , why they do not appear to me?

  19. hi,
    Excelent tutorial, I am also looking for overlaped top navigation menus one over on other like tabs on mouse over. if any you have please share…
    thanks
    vinod

  20. Hi Mary, Thanks for such a wonderful tutorial.You are a inspiration for us. Thanks once again. Can we use it in the live environment?

  21. Same as comments above great menu but doesnt work in IE7, IE8 and IE9

    the overlay css is read before the JS so it shows the background as black, until the menu is activated, anyone able to help??

  22. Just a follow up on my last comment.

    I changed oe_overlay to background-color: #000000; rather than background:#000000; and it seems to work.

    Need to do some proper testing but so far so good…
    Just thought this may help others as IE doesnt support the background only tag.

  23. I just changed the background as you said, but it still does not work.
    Can you prepare some package that works on yours computer ?

  24. what do i need to do to make this no conflict?

    i need it to work in joomla.

    and i need it to work with several other jquery.

    thanks

  25. wew \(0,0)/
    a woman.. haha
    hi miss mary lou
    btw great tut
    i just know this site LOL

  26. How do I get any clickable content in the main area. Its overshadowed by the z-index and any hrefs don’t work. anybody have any working example for that?