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!

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

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!

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

👾 Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!

Feedback 83

Comments are closed.
  1. I am having the same problem as ADI. None of my links work, because they are behind the overlay. Has anyone found a way to fix this?

  2. Hi Mary
    I have the some problem as DLV at the first coment.
    I tray the code posted by Chris but it don’t work.
    I have my site almost ready, and I appreciate very much if you can post the code with that change.
    thanks

  3. Hi Amanda,

    I fixed it by setting the overlay’s display property to none using hide() with the following change:

    $oe_overlay.stop(true,true).fadeTo(200, 0, function(){ $oe_overlay.hide(1); });

    However, inserting/removing the overlay using JS would be a more elegant way of solving this like it was suggested at the top of the comments.
    I couldn’t make it work using append() and remove() though.

  4. Hi guys!
    Tanks for tutorial
    I ask you to add the string below in downlodable version because it not working properly on explorer

    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);

    so this work good on explorer:

    .oe_overlay{
    background:#000;
    opacity:0;
    position:fixed;
    top:0px;
    left:0px;
    width:100%;
    height:100%;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
    }

    I find it on on-line css demo

    thanks
    ALL THE BEST!

  5. Hi Mary
    I have the some problem as DLV at the first coment.
    I tray the code posted by Chris but it don’t work.
    I have my site almost ready, and I appreciate very much if you can post the code with that change.
    thanks

  6. Hi

    I am trying to achieve a body width div and I tried to change the ul.oe_menu div and few other items with that width but the drop down keeps shifting to the right and doesnt align in the middle.

    Would appreciate it if you could guide me on how to achieve this.

    Many thanks

  7. hi,

    how can i put link in to the main content , it isn’t clickable .
    Help me , how can i use ?

  8. Oops, sorry:
    meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE8″ /

  9. Has anyone actually got this menu to work with IE?? I have tried all of the suggestions without any luck..

    Thanks in advance..

  10. I don’t have drop downs for all of the menu boxes. When I hover over one that DOES have a dropdown and then slide my mouse to hover over one that DOESN’T have a dropdown, the dropdown box from the previous menu item doesn’t disappear. How do I fix this?? I know it has something to do with the jquery….please help!!!

    http://www.dominowa.janinepietzphotography.com

    I can’t get the overlay effect to go away either. If I try to click on a hyperlink in the main page content, I have to hover my mouse over the menu bar again and then the links work. Strange…

  11. PLEASE help! I can’t get mine to work like the demo. In IE (I’ve tested versions 7 8 and 9), when you go to the home page, the overlay shows up and makes the background dark until you put your mouse over the menu. I’ve recopied the css and jquery and it still won’t work. Help!

    http://www.dominowa.janinepietzphotography.com

  12. GREAT navigation effect!

    Doesn’t work on IE?
    I dont care, just let IE die or compaint to microsoft IE team to make some better work! stupidbrowser!

  13. How do you slow down the speed between large image previews? My client wants them to transition more slower.

    Also, how do you put the close button when viewing the large images within the image itself instead of all the way on the right corner of the site?

  14. I got the same problem as “pietza”:
    I can’t get mine to work like the demo. In IE (I’ve tested versions 7), when you go to the home page, the overlay shows up and makes the background dark until you put your mouse over the menu. I’ve recopied the css and jquery and it still won’t work.

  15. It’s really an amazing menu! It work on safari, ff and chrome but not on IE…i tried the suggestions of the previous post, but without success.
    Someone have a fix?

  16. I got the same problem as “marcosmac” all my links and text are no more active because of z-index.

    Any idea to solve it? thanks a lot!
    Great job!

  17. Hi,
    I am trying to change the menu for the event “click” more is not working.
    someone could help me?

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

  18. if anyone have problem with clicking elements then use this script instead :

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

    $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′);
    });

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

  19. Hi,

    Thanks for the great jquery and simple tutorial. However, like many others before me I’ve encountered a big issue, namely, the rest of my hyperlinks don’t work.

    I’ve noticed the same issue on the demo page – the only other links that work are in the “reference class”. One can’t even select simple paragraph text.

    I’ve been cracking my head trying to figure it out, to no avail. A workaround would be much appreciated. I hope some gurus out there have a few ideas…

    Thanks in advance

  20. I finally figured out a way around the inaccessible text and hyperlinks after implementing the menu. It’s the oe_overlay class.

    I’m not sure how my solution will affect folks who are actually using this menu for the wonderful overlay effect (I just like the look and feel of the menu element itself), but if you remove or comment out the
    “” in your markup, you’ll be fine… i’m sure there’s a js workaround for this, but this has worked just fine for me.

  21. arman’s code above works for the inactive links. you have to change the closing apostrophes, but aside from that it works fine. IE, however…