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!

que buen menu.. exelente trabajo, con su permiso lo utilizare para mi futuros proyectos…
=)
Great !!
Perhaps better with background image…
@Jireck That’s a nice idea, do you mean a repeated background or something like a big photo? Cheers, ML
Yea, but CSS2 support? IE7 silly drops it…
Enyway nice.
Amazing as usual, even more if you look at the demo with a 1920×1200 px monitor ;)
Another great looking script. Indeed it would look great with a large image on the background. Thanks again for sharing :-)
Oh it make a very nice effect, I wil use it for the next project
Is there any possibilities to add .current class i mean the active page status Mary Lou.
That is hot!
This is not compatible with IE7 atleast. we can ignore IE6 but can’t ignore the IE7 and IE8 and IE9.
Hello Fem, it works fine in IE8 (of course, without the rounded borders since that is CSS3). Actually we should ignore every version except the latest one, which is IE8. Cheers, ML
always awesome created tutorial…WOW
Is it possible that if you can make it compatible with IE7 as well, I can pay you for doing so. As my client likes it very much and he want to use this menu.
Hi there! Many thanks for the tutorial. Amazing as usual.
Help needed: I would like to use accentuated letters.
Many thanks, indeed.
Hi! I think, when you created your font here you need to check as well the box for “Latin-1 Supplement” for accented characters. I hope it helps! Cheers, ML
Oh, many thanks. You’re so great. What a quick support! Problem solved.
:-)
Wow ! Very cool ! :)
Just as a proof of concept, I took fly out menu and ripped out the JS and without much tweaking, here’s a pure CSS3 implementation to achieve a similar effect. (chrome only)
http://commondatastorage.googleapis.com/thurloat/css3demo.html
@Adam That’s really cool! Cheers, ML
Strongly disagree that support for ie7 should be dropped. According to W3, IE7 has a 9.1% and IE6 has a 7.1% marketshare. It seems odd to me that you would compromise navigation for 16% of users (to be fair, I don’t know that many people browsing your site would use ie6/ie7).
what is so “awesome” about that? i don’t get it. just the fact that you can make it with a certain mix of technologies doesn’t make an old (most time lame) idea awesome. sorry folks. :-)
Excellent tutorial and implementation.
A very thorough tutorial, but then let down at the very end. Did you run out of time to explain that final step?
It got me that far though – I’ll do some trial-and-error with the cufon stuff to finish off on my own.
Thanks.
Martin