Awesome Cufonized Fly-out Menu with jQuery and CSS3

In today’s tutorial we will create a full page cufonized menu that has two nice features: when hovering over the menu items we will move a hover-state item that adapts to the width of the current item, and we will slide out a description bar from the left side of the page, reaching towards the […]
flyoutmenu

From our sponsor: Design every part of your website with the Divi Theme Builder.

In today’s tutorial we will create a full page cufonized menu that has two nice features: when hovering over the menu items we will move a hover-state item that adapts to the width of the current item, and we will slide out a description bar from the left side of the page, reaching towards the current menu item.

We will use jQuery for the effect and some CSS3 properties for the style. We are not going to use any images.

So, let’s start!

The Markup

The HTML structure will consist of an unordered list that represents our menu and a div for the description elements:

<div id="slidingMenuDesc" class="slidingMenuDesc">
	<div><span>Description for "About"</span></div>
	...
</div>

<ul id="slidingMenu" class="slidingMenu">
	<li><a href="#">Home</a></li>
	<li><a href="#">About</a></li>
	<li><a href="#">Portfolio</a></li>
	<li><a href="#">Work</a></li>
	<li><a href="#">Contact</a></li>
	<li><a href="#">Get a quote</a></li>
</ul>

We leave out the description for “Home” since there is nothing to describe. The sliding divs should just appear when we hover over the other items.

The CSS

First, we will style the menu and its navigation items and then we will style the description elements.
Let’s reset some styles:

body, ul, li, h1, h2, span{
	margin:0;
	padding:0;
}
ul{
	list-style:none;
}

The background is going to be dark gray:

body{
	background:#292929;
}

The list for the menu items is going to be positioned absolutely at the right side of the screen:

.slidingMenu {
	position: absolute;
	height:410px;
	width: 410px;
	top:40px;
	overflow:hidden;
	right:1px;
	font-family: Arial, Helvetica, sans-serif;
}

The menu items are hoing to float right:

.slidingMenu li {
	display:block;
	float:right;
	clear:both;
	position:relative;
	overflow:hidden;
}

The “mover” element will be positioned absolutely and we will give it a top and a width dynamically:

.slidingMenu li.move {
	width: 9px;
	height: 68px;
	right:0px;
	padding-right:10px;
	margin-top:2px;
	z-index: 8;
	position: absolute;
	background: #2183c4;
	background:
		-webkit-gradient(
			linear,
			left top,
			left bottom,
			from(#0771b8),
			to(#2183c4)
		);
	background:
		-moz-linear-gradient(
			top,
			#0771b8,
			#2183c4
		);
	-moz-border-radius: 8px 0px 0px 8px;
	-webkit-border-top-left-radius: 8px;
	-webkit-border-bottom-left-radius: 8px;
	border-top-left-radius: 8px;
	border-bottom-left-radius: 8px;
	-moz-box-shadow:1px 1px 5px #000;
	-webkit-box-shadow:1px 1px 5px #000;
	box-shadow:1px 1px 5px #000;
	}

We will give this moving hover element a very subtle background gradient and some box shadow.
The style for the link element will be as follows:

.slidingMenu li a {
	font-size:66px;
	text-transform:uppercase;
	text-decoration: none;
	color: #ddd;
	outline: none;
	text-indent:5px;
	z-index: 10;
	display: block;
	float: right;
	height: 66px;
	line-height: 66px;
	position: relative;
	overflow: hidden;
	padding-right:10px;
}

The descriptions will be in a relatively positioned container. We set the margin-top to the same value like the top of the menu list:

/* Descriptions */
.slidingMenuDesc{
	margin-top:40px;
	position:relative;
}

The div with the description span inside is going to have the same background-gradient like the mover and the same box shadow. The rounded borders are going to be on the opposite corners:

.slidingMenuDesc div{
	background: #2183c4;
	background:
		-webkit-gradient(
			linear,
			left top,
			left bottom,
			from(#0771b8),
			to(#2183c4)
		);
	background:
		-moz-linear-gradient(
			top,
			#0771b8,
			#2183c4
		);
	height: 68px;
	padding-right:5px;
	left:-5px;
	width:0px;
	margin-top:2px;
	overflow:hidden;
	position:absolute;
	-moz-box-shadow:1px 1px 5px #000;
	-webkit-box-shadow:1px 1px 5px #000;
	box-shadow:1px 1px 5px #000;
	-moz-border-radius: 0px 8px 8px 0px;
	-webkit-border-top-right-radius: 8px;
	-webkit-border-bottom-right-radius: 8px;
	border-top-right-radius: 8px;
	border-bottom-right-radius: 8px;
}

We need to set these element absolute, since we will adjust the top to the according current list element that we are hovering.

The description span is going to be positioned absolutely as well. This is not required but it gives you more options if you would like to apply other animation effects:

.slidingMenuDesc div span {
	font-size:36px;
	color: #f0f0f0;
	text-indent:5px;
	z-index: 10;
	display: block;
	height: 66px;
	line-height: 66px;
	position:absolute;
	right:10px;
	margin-left:5px;
	top:-3px;
}

And now, let’s take a look at the JavaScript!

The JavaScript

First, we will add the following scripts to our HTML head:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="cufon-yui.js" type="text/javascript"></script>
<script src="BabelSans_500.font.js" type="text/javascript"></script>
<script src="jquery.easing.1.3.js" type="text/javascript"></script>

And we will add the following script:

$(function() {
	Cufon.replace('a, span').CSS.ready(function() {
		var $menu 		= $("#slidingMenu");

		/**
		* the first item in the menu,
		* which is selected by default
		*/
		var $selected	= $menu.find('li:first');

		/**
		* this is the absolute element,
		* that is going to move across the menu items
		* It has the width of the selected item
		* and the top is the distance from the item to the top
		*/
		var $moving		= $('<li />',{
			className	: 'move',
			top			: $selected[0].offsetTop + 'px',
			width		: $selected[0].offsetWidth + 'px'
		});

		/**
		* each sliding div (descriptions) will have the same top
		* as the corresponding item in the menu
		*/
		$('#slidingMenuDesc > div').each(function(i){
			var $this = $(this);
			$this.css('top',$menu.find('li:nth-child('+parseInt(i+2)+')')[0].offsetTop + 'px');
		});

		/**
		* append the absolute div to the menu;
		* when we mouse out from the menu
		* the absolute div moves to the top (like initially);
		* when hovering the items of the menu, we move it to its position
		*/
		$menu.bind('mouseleave',function(){
				moveTo($selected,400);
			  })
			 .append($moving)
			 .find('li')
			 .not('.move')
			 .bind('mouseenter',function(){
				var $this = $(this);
				var offsetLeft = $this.offset().left - 20;
				//slide in the description
				$('#slidingMenuDesc > div:nth-child('+ parseInt($this.index()) +')').stop(true).animate({'width':offsetLeft+'px'},400, 'easeOutExpo');
				//move the absolute div to this item
				moveTo($this,400);
			  })
			  .bind('mouseleave',function(){
				var $this = $(this);
				var offsetLeft = $this.offset().left - 20;
				//slide out the description
				$('#slidingMenuDesc > div:nth-child('+ parseInt($this.index()) +')').stop(true).animate({'width':'0px'},400, 'easeOutExpo');
			  });;

		/**
		* moves the absolute div,
		* with a certain speed,
		* to the position of $elem
		*/
		function moveTo($elem,speed){
			$moving.stop(true).animate({
				top		: $elem[0].offsetTop + 'px',
				width	: $elem[0].offsetWidth + 'px'
			}, speed, 'easeOutExpo');
		}
	}) ;
});

After we cufonize the font (all “a” elements and all “span” elements), the main function gets executed. We select the first item by default which is our “Home”. When we hover over a menu item we will move the li.move to the right position and slide out the according description item.

And that’s it! We hope you enjoyed it and find it useful!

Tagged with:

Mary Lou

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.

http://www.codrops.com

Stay up to date with the latest web design and development news and relevant updates from Codrops.

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 115

Comments are closed.
  1. I cannot get this to work 🙁
    I have the nav menu, but none of the blue animation or bars appear. All I have is the grey background and the the nav words 🙁
    Any suggestions? Martin

  2. Has anyone created a working version compatible with IE7? If so, I’d love to see a demo… Thanks!

  3. I am attempting to use this piece as a part of my project. I can’t for the life of me get a background image to load via css or html. Help? I’ve also been trying to constrain the whole thing within another <div that is sized specifically w1152xh1200. Is this possible?

  4. Great menu, very compliments!
    But can someone explain me why you have to use
    ‘li:nth-child(‘+parseInt(i+2)+’)’
    and not
    ‘li:nth-child(‘parseint(i+2)’)’
    when declaring ‘top’ in the slidingMenuDesc?
    and why i+2 and not i?
    Thank you very much!

  5. Well, what if I want to use this for page sessions, how can I make it so that if I want “portfolio” to be the main selected menu, and then change if I go back to home, and so forth with the rest of the sessions.
    Any ideas?

  6. i love the effect and i would live to know how i can make th emenu onclick always open that i can include more information , links and images inside the , any idea

    thanks

  7. QUISIERA USAR ESTE MENU PERO DOBLE EN ALGUNA PAGINA PERO HE INTENTADO HACER EL EFECTO AL CONTRARIO PERO NO LOGRO HACER QUE LA PARTE QUE SE MUEVE ENCAJE PERFECTAMENTE .. ES DECIR LOGRO HACER QUE LA ANIMACION SALGA DE DEREECHA A IZQUIERDA PERO NO LOGRO HACER QUE LLEGUE JUSTO A DONDE TERMINA CADA PALABRA COMO LO HACE EL CODIGO ORIGINAL …. ME GUSTARIA QUE ME PUDIERAN DECIR QUE VARIABLE CAMBIO EN EL CODIGO JAVASCRIPT PARA HACER QUE ESTA ANIMACION FUNCIONE HACIA EL OTRO LADO

  8. @ML, you’re like a designers magnet! This concept rocks, as per usual for you 🙂
    Btw I used a background slider with the browser constrained to 1024×768 and this menu of yours works like a charm.

    I am having difficulty contraining the menu within a ‘main’ div where the page content is centered. I manage to lock down the description (left) of the menu, but not the right. I’ll keep on trying, but if you have an idea of how to lock it down to a div instead of the browser, that would be great. Not sure it is designed to do that though.

  9. Ok, managed to get this menu working in a div width. I am just experiencing one weird effect and that is the description div flying out too far and overlapping the menu div that then caused the option to be obscured and a lot of jitter.
    Anyone have any ideas as to how the fly-in can be controlled in terms of the amount the description div is expanding across the width of the page / div? I do not find any option in either the CSS or JS to change this…

  10. Clarification – when I run the above inside a div (I use it with a slider as a background – ML, that looks great btw) and when viewed in a 1024 x 768 sized browser, looks perfect.

    When I expand it to my own maximum, iow beyond a standard resolution, the description span flies out much further and ends up obscuring the menu div and that causes jitter, all during the mouse over event. Is the length (width) of the span tied to the screen through the js or is there some CSS I need to amend that I am missing?

  11. Dude.. This is amazing.. I really loved it, and thanx for sharing the most significant style with CSS3.. I’ve tried many places before but this one is awesome..

    Thanx Dude!!!!!
    Really Loved it!!
    You are CSS ROCKSTAR!!!!!!

  12. Hey thanks for this, I am so excited to put it to use. I was wondering if there is a way to have the nav be persistent, so that when the page scrolls down, the nav follows?

    Thanks,
    Kris

  13. First of all, Mary Lou, this is an absolutely fantastic tutorial. I’m working on redesigning our website with a menu based on this, but I was just wondering how you would go about switching the sides so that the menu items appear on the left and the slide out text comes from the right.

  14. Thank you for this! I am having problems though implementing this in WordPress. Do I just upload the .zip file into the site?

  15. What should I change in code lines to get opposite effect? List for the menu items is going to be positioned absolutely at the right side of the screen. I want menu positions at the left side of screen and divs with the description span inside move to the right. Simply say: I need mirror reflection of this effect. Is this possible? Can you show me how to do this? Please 🙂

  16. Love the script, but I’m wondering if you can help with a problem!

    Basically, as soon as I insert a separate slideshow gallery, this menu stops working.

    This is what I’m inserting: