From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
Today we will create a collapsing menu that contains vertical navigation bars and a slide out content area. When hovering over a menu item, an image slides down from the top and a submenu slides up from the bottom. Clicking on one of the submenu items will make the whole menu collapse like a card deck and the respective content area will slide out.
The beautiful fashion photos are taken from Beyrouth’s photostream on flickr. The specific set can be found here.
So, let’s get started!
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
Our HTML will consist of a main container with the class and id “cc_menu”. Here we will place all our vertical menu items and the main content div:
<div id="cc_menu" class="cc_menu"> <div class="cc_item" style="z-index:5;"> <img src="images/1.jpg" alt="image" /> <span class="cc_title">Collection</span> <div class="cc_submenu"> <ul> <li class="cc_content_1">Winter 2010</li> <li class="cc_content_2">Spring 2011</li> </ul> </div> </div> <div class="cc_item" style="z-index:4;"> <img src="images/2.jpg" alt="image" /> <span class="cc_title">Stores</span> <div class="cc_submenu"> <ul> <li class="cc_content_3">Milano</li> <li class="cc_content_4">Paris</li> </ul> </div> </div> ... <div id="cc_content" class="cc_content"> <span id="cc_back" class="cc_back"><< Go back</span> <div class="cc_content_1"> <h1>Winter 2010</h1> <p>Some content</p> </div> <div class="cc_content_2"> <h1>Spring 2011</h1> <p>Some content</p> </div> ... </div> </div>
The first item will get a z-index of 5 and then we will decrease the z-index for the next items. This will make the last item be in the lowest layer. We do this in order to create the card deck collapsing effect.
Each submenu item will share its class with the respective content div. Like that we can make the right content div appear whenever we click on a submenu item.
Let’s take a look at the styling.
The CSS
Our main div that surrounds everything will have the following style:
.cc_menu{ width:700px; /*140px * 5*/ height:600px; position:relative; font-size:14px; text-transform:uppercase; color:#fff; }
The width of this container is the sum of all the item widths which is 5 times 140 pixels.
The style of each navigation item will be the following:
.cc_item{ text-align:center; width:140px; height:600px; float:left; border-bottom:1px solid #000; background:#444 url(../images/bg.png) repeat top left; position:relative; -moz-box-shadow:3px -3px 10px #000; -webkit-box-shadow:3px -3px 10px #000; box-shadow:3px -3px 10px #000; }
We will give each item a box shadow so that the layering becomes visible. (That does not work in IE yet, so you will have to add a border or some other background image that enhances this.)
The title in each menu element will have a dark background with a subtle shadow around:
span.cc_title{ color:#fff; font-size:16px; top:200px; left:5px; position:absolute; padding:3px 0px; background:#111; width:130px; display:block; z-index:11; -moz-box-shadow:1px 1px 4px #000; -webkit-box-shadow:1px 1px 4px #000; box-shadow:1px 1px 4px #000; }
The submenu list will be styled as follows:
.cc_submenu ul{ list-style:none; width:140px; margin:0; padding:0; height:0px; /*increase to 200px to slide up*/ overflow:hidden; text-align:left; background:#000; position:absolute; left:0px; bottom:0px; opacity:0.7; z-index:13; }
We will position the list at the bottom of the item and give it a height of 0 pixel. We will then increase the height to 200 pixels for it to slide up from the bottom.
The list elements of the submenu list will have the following style:
.cc_submenu ul li{ color:#ddd; cursor:pointer; padding:10px; }
The image that will slide in from the top will be positioned negatively, meaning that we will hide it at the top of the item and the page:
.cc_item img{ position:absolute; width:140px; height:600px; top:-600px; left:0px; }
In our JavaScript function we will make it slide down from the top by animating the top value to 0px.
The div that surrounds all the contents will also be hidden to the left of the page by setting the left value to -700 pixels:
.cc_content{ width:600px; height:600px; border-bottom:1px solid #000; position:absolute; left:-700px; background:#444 url(../images/bg.png) repeat top left; overflow:hidden; -moz-box-shadow:4px 0 7px #000; -webkit-box-shadow:4px 0 7px #000; box-shadow:4px 0 7px #000; }
The single content divs will have the following style:
.cc_content div{ display:none; margin:20px; }
We will give each paragraph the following style:
.cc_content p{ background:#000; padding:20px; opacity:0.7; }
And finally, we will position the back span at the bottom right of the content container:
span.cc_back{ position:absolute; bottom:10px; right:10px; cursor:pointer; color:#ddd; }
And that was the style. Now, let’s take a look at the JavaScript magic.
The JavaScript
We will have several function taking care of the behavior of our navigation. Whenever we hover a menu item, we want the image to slide in from the top and the submenu to slide in from the bottom. And, of course, when we leave an item, we want the reverse to happen. The functions m_enter and m_leave take care of that behavior.
The function fold will make the menu collapse once a submenu item is clicked. The initial position is recovered by the function unfold.
The two functions showContent and hideContent take care of the respective content appearing and disappearing.
In our main jQuery function we will start by defining some variables:
//all the menu items var $items = $('#cc_menu .cc_item'); //number of menu items var cnt_items = $items.length; //if menu is expanded then folded is true var folded = false; //timeout to trigger the mouseenter event on the menu items var menu_time;
Now we will bind the mouseenter and the mouseleave to each item. We will also bind the click event to list elements in the submenu:
$items.unbind('mouseenter') .bind('mouseenter',m_enter) .unbind('mouseleave') .bind('mouseleave',m_leave) .find('.cc_submenu > ul > li') .bind('click',function(){ var $li_e = $(this); //if the menu is already folded, //just replace the content if(folded){ hideContent(); showContent($li_e.attr('class')); } else //fold and show the content fold($li_e); });
In the following we will define the m_enter function:
function m_enter(){ var $this = $(this); clearTimeout(menu_time); menu_time = setTimeout(function(){ //img $this.find('img').stop().animate({'top':'0px'},400); //cc_submenu ul $this.find('.cc_submenu > ul').stop().animate({'height':'200px'},400); },200); }
The timeout is used to prevent this event to trigger if the user moves the mouse with a considerable speed through the menu items.
The m_leave function is defined as follows:
function m_leave(){ var $this = $(this); clearTimeout(menu_time); //img $this.find('img').stop().animate({'top':'-600px'},400); //cc_submenu ul $this.find('.cc_submenu > ul').stop().animate({'height':'0px'},400); }
When clicking on the back span, we want the unfold function to trigger:
$('#cc_back').bind('click',unfold);
The fold function will show only the menu column of the chosen submenu and make all the other items animate to the left by setting the margin to -140 pixels:
function fold($li_e){ var $item = $li_e.closest('.cc_item'); var d = 100; var step = 0; $items.unbind('mouseenter mouseleave'); $items.not($item).each(function(){ var $item = $(this); $item.stop().animate({ 'marginLeft':'-140px' },d += 200,function(){ ++step; if(step == cnt_items-1){ folded = true; showContent($li_e.attr('class')); } }); }); }
The unfold function shows all the menu items and also hides any item’s image and submenu that might be displayed:
function unfold(){ $('#cc_content').stop().animate({'left':'-700px'},600,function(){ var d = 100; var step = 0; $items.each(function(){ var $item = $(this); $item.find('img') .stop() .animate({'top':'-600px'},200) .andSelf() .find('.cc_submenu > ul') .stop() .animate({'height':'0px'},200); $item.stop().animate({ 'marginLeft':'0px' },d += 200,function(){ ++step; if(step == cnt_items-1){ folded = false; $items.unbind('mouseenter') .bind('mouseenter',m_enter) .unbind('mouseleave') .bind('mouseleave',m_leave); hideContent(); } }); }); }); }
The function to show the content will animate our content container to the right by setting the left value to 140 pixels. It will also fade in the respective content:
function showContent(idx){ $('#cc_content').stop().animate({'left':'140px'},200,function(){ $(this).find('.'+idx).fadeIn(); }); }
And finally, the function to hide the content:
function hideContent(){ $('#cc_content').find('div').hide(); }
To cufonize the font in our menu, we will simply add these lines to the head of our HTML:
<script src="js/cufon-yui.js" type="text/javascript"></script> <script src="js/Liberation_Sans.font.js" type="text/javascript"></script> <script type="text/javascript"> Cufon.replace('span'); Cufon.replace('li'); Cufon.replace('h1'); Cufon.replace('p'); </script>
We will be using the font Liberation Sans which you can also find here.
And that’s all! We hope you enjoyed this tutorial and find it useful!
WOW!
Great!!!
Codrops rocks!!(as usual)
I have a question: how to change Images dynamically via ajax for each hover effect?
I lub your stuff. Always amazing 🙂 Great job ML
amazing, thanks!
AWESOME………
This navigation is really awesome. Thanks for sharing.
And your tuts are so intuitive to follow.
Welcome back!!!
awsome job!!!!!!!!
welcome back guys,
hope you have good times this summer:)
thanks for this tut!
always unique!!!
Holly mother and god! That is so awesome! You always came out with something gorgeous and slick!
Congrats for that!
nice effect! glad u r back!
Perfect Effet and tutos, Mary-Lou
Why you use Span class=”cc_title” and not use h1 class=”cc_title”, you remplace h1 by h2 in your code and all your content is hierachic … ? and right balise (h) is in right place ?
I hope you understand what i mind
Wow! Great job again! Missed you guys!
Thanks Wayne, it’s good to be back! Thank you all for your great comments!
@Jireck you are completely right, I guess I still have too much sand in my brain 😀
this is an amazing tutorial, thanks!
My GOD! Your creativity in fantastic.
Thanks, Thanks, Thanks!
Great !!!!!!!!!!!!!
You have some of the coolest tutorials on the web, as far as I know. Thanks for sharing!
@Mary Lou
I have rigid mind and alway apply standard. You have imagination, write excellent code and tutos …
Stay with sand in your brain… 😉
Very Nice Thanx
Great Job
This is AWESOME! THANK YOU! Just a quick question though. How would I get this in the center of the page. I have already tried putting the menu in a div with the margin left and right set to auto, but it still does not work properly.
Please tell me that there is some clever person out there that can help, lol. Thanks a mill for the sweet structure though. It Rocks.
wow…its like a:hover
so smooth…ck ck ck
ajeijeijeije…
Sweeeet. Love it! 😀
Great, very nice effect..
freakin’ awesome!!!
i’m really amazed! can i get some support of one of you please!! i’m kinda lost and here, in argentina, i haven’t meet anyone who knows what JQuery is, i just read but there’s a coupple of things that i can’t figure out by myself.. please?? samebody’??
@emmanuele Just post your questions or send us an email, we’ll try to help! 🙂 Cheers, ML
is there a way to get this at 100% of screen width and height? or menus at least at 100%
menu heights at 100% is what i meant by that last part.
also having mootools-jquery conflict issues.
Great desing, just as every design in this page!! cheers!
I really like this, but is there a way of making the menu (constrained) fluid and at 60% height so that it sits in the centre of the screen but fills most of the screen at any browser size?
This is the best navigation menu ever!!! Simply great!
I´m trying to change it to fit my need but i´m having some problem on understanding the code.
How can i change the behavior of the onmouseover for onclick?
Where on mouseover show the picture and the submenu, i would like to make it appear by clicking it.
Does anyone can give me some directions on how to do it?
Thanks in advance
Hey there. Top notch little navigation system you’ve come up with. I was just wondering how I would go about adding a different image to each fold away section?
The effect I’m thinking of is a black and white photo spanning the different navigation sections that is there constantly. On rollover a colour version replaces that section of the photo. When a link is clicked the photo then folds up in sections showing a plain colour background for the content.
Any ideas? I’ve tried myself by wrapping the “cc_item” in a div but it ruins the collapse. I’m no good with javascript so can’t work out how to fix it.
Any help would be appreciated.
Kev.
Anyone else have display issues with the demo in IE9?
WOW!!
can we actually load content dynamically through javascript
i wanted to connect this script to joomla and then draw contents from the database.
Could u please help
This Slider is awesome !
how would one put an iframe in between the slide out menu heading and paragraph text?
seems something went wrong with my previous comment, things went missing, so again….
i was wondering if it is possible to have a “a href=”#A” “a name=”A”
linking style from a link outside the slider to a open slider info box
so from a link as from “span class=”reference”
to a box (cc_content_1)
so the box will slide open and show the text
anyone knows how to do this
thx
on my search if it is possible to use an anchor link to open a (cc_content_1) section i think something have to be modified in the .js script.
on a forum i saw this .js below which i think can be “the” or “part” of the solution to my former question.
but i know far to less about scripting to know how to use it, can someone assist me in this ?
thx
function reloadAndJump(anchor)
{
location.replace(‘http://www.example.com/mypage.html#’ + anchor);
return false;
}
Awesome tutorial yet again. Has anyone figured out how to make this centered. the div that contains the whole menu is give a position of -700 to make it hidden which would work since it is left aligned but not for a centered menu. Any idea as to what I can adjust to make this happen.
Great tutorial!!!!
but how you make it centered the hole menu ??? I move the “.cc_menu¨” but the “cc_content” i cant move it to center thnxs
Im tryint to use this beatifull gallery but its not working…. What am i doing wrong??? I have trid as much as possible…. HELP!!!!!!!!
Great tutorial! I have a question though.
Let’s say I have a lof of content for one page and I want to create a ‘Next Page’ link at the bottom (where the link ‘Go Back’ is) and when you click it, I will go to the next page of the same link. Is there anyway that you can help me on that?
Much appreciated!
beautiful tutorial, Nice
Hi, could someone help me i keep geting this error
syntax error
[Break On This Error] $this.find(‘img’).stop().animate(,400);
How cani i replace this
Hello
I do my index with this, centering.
But Can we justify text on cc content?
you can see my pb here:
http://www.benjaminrinaldi.com
congrats again for your work
Mary good work. I’m figuring out how to centre this but really great stuff.
Kev, surely you just need a screenshot of the site, whip it in Photoshop, and then use it as a quick guide with the image you want to use on another layer, choppy choppy!
LOVE THIS! You are awesome!
Hello
Thx a lot for this great tutorial !
I just had a little problem that i can’t solve, can you help me please ?
If i try to insert a div into the content (“cc_content” class) it’s not visible!
Code :
Winter 2010
TEST-CONTENTFar far away, behind the word mountains, far from …
thx a lot !
very beautiful and useful, thanks.
Mary, you rock this jquery!!!!!!