From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
In this tutorial we will create a fixed menu with scrollable thumbs. The idea is to have a menu fixed to the bottom of the page and let a vertical stack of thumbs appear when hovering over a menu item. The thumbs are scrollable by moving the mouse up and down which makes a really nice effect. We will add some CSS3 properties for spicing up the looks.
We will base our jQuery code on the Vertical Scrolling Menu of Andrew Valums.
The images used in the demo are from the incredible fashion photo collection by kk+ on flickr.
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
The HTML is pretty straightforward. We have an unordered list with a link element and wrapper div that contains the menu with the thumbs:
<ul class="menu" id="menu"> <li> <a href="#">Brand 1</a> <div class="sc_menu_wrapper"> <div class="sc_menu"> <a href=""><img src="images/1.jpg" alt=""/></a> <a href=""><img src="images/2.jpg" alt=""/></a> ... </div> </div> </li> ... </ul>
I just show an excerpt here, since it already outlines how to build the structure.
Let’s have a look at the style.
The CSS
First, we will set that any overflow of the body will not show any scrollbars:
body{ overflow:hidden; }
This is not really necessary for this to work but it just looks very nice and if there is not much else in the page, it is not really problematic.
/* Navigation Style */ ul.menu{ list-style:none; font-family: "Trebuchet MS", Arial, sans-serif;; font-size: 15px; font-style: normal; font-weight: normal; text-transform:uppercase; letter-spacing: normal; line-height: 1.45em; position: fixed; bottom:0px; left:0px; width:700px; height:100%; }
If you want your page to be scrollable, then make sure to set the menu fixed, if you want it to stick to the bottom of the page. The list elements and the links will be styled as follows:
ul.menu li{ float:left; position:relative; height:100%; width:130px; } ul.menu li > a{ position:absolute; bottom:0px; left:0px; width:130px; height:40px; text-align:center; line-height:40px; color:#ddd; background-color:#291A2F; letter-spacing:1px; cursor:pointer; text-decoration:none; text-shadow:0px 0px 1px #fff; -moz-box-shadow:-1px 0px 5px #000; -webkit-box-shadow:-1px 0px 5px #000; box-shadow:-1px 0px 5px #000; opacity:0.9; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=90); }
OK, before people start ranting now, no, we don’t need a link element, we might as well use a span or whatever. I am just so traditional. I will start using non-link elements next time 🙂
With a white text shadow behind a white text, we get a slight blur of the font which gives a smooth effect (especially in Chrome). That last ugly line is the opacity filter for IE.
Be careful using that crappy filter on png images that have some (semi-)transparent parts: IE fills it out with charming BLACK.
The style for the thumb menu wrappers will look as follows:
/* Thumb Scrolling Style */ div.sc_menu_wrapper { position: absolute; top:0px; width:150px; overflow: hidden; bottom:0px; left:0px; visibility:hidden; } div.sc_menu { width:130px; visibility:hidden; }
Now, why do we use visibility:hidden here? We have two reasons: one is that we want to make the thumbs appear as if we stack them from bottom to top, so we already “place” the elements there and then just set them visible (see in the JS). With display:none, you actually make the element not taking any width or height in the page, but with visibility:hidden we still occupy the space, the element is just not “visible”.
The reason why we do that to the wrappers is because of the scrolling function in jQuery that gets the height of the elements. If our element is not displayed, that’s not really possible. Visibility solved that issue.
The thumb links and the thumb images are styled as follows:
.sc_menu a { display: block; background-color:#22002F; color: #fff; text-align:center; -moz-box-shadow:3px -3px 3px #3B0F4F; box-shadow:3px -3px 3px #3B0F4F; -webkit-box-shadow:3px -3px 3px #3B0F4F; } .sc_menu img { display: block; border: none; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); }
That was the style and now, let’s add some magic!
The JavaScript
The main idea is to build the thumbs menu when we hover over the main navigation items. We show the thumbs in a stacking order, one after the other, with a time delay (line 34-44).
The “buildThumbs” function will let us scroll through the thumbs without a scroll bar, by moving the mouse to the top or to the bottom.
The “inactiveMargin” let’s us reach the topmost and the bottommost thumbs better, so that we can actually see the images entirely and not cut off.
Initially, we want to start at the bottom, so we scroll down (line 13).
When we leave the main list items, we put everything back to normal, we hide everything again (line 49-58).
When we hover over the thumbnails, we will change the opacity (line 62-75)
$(function(){ /* function to make the thumbs menu scrollable */ function buildThumbs($elem){ var $wrapper = $elem.next(); var $menu = $wrapper.find('.sc_menu'); var inactiveMargin = 150; /* move the scroll down to the beggining (move as much as the height of the menu) */ $wrapper.scrollTop($menu.outerHeight()); /* when moving the mouse up or down, the wrapper moves (scrolls) up or down */ $wrapper.bind('mousemove',function(e){ var wrapperHeight = $wrapper.height(); var menuHeight = $menu.outerHeight() + 2 * inactiveMargin; var top = (e.pageY - $wrapper.offset().top) * (menuHeight - wrapperHeight) / wrapperHeight - inactiveMargin; $wrapper.scrollTop(top+10); }); } var stacktime; $('#menu li > a').bind('mouseover',function () { var $this = $(this); buildThumbs($this); var pos = $this.next().find('a').size(); var f = function(){ if(pos==0) clearTimeout(stacktime); $this.next() .find('a:nth-child('+pos+')') .css('visibility','visible'); --pos; }; /* each thumb will appear with a delay*/ stacktime = setInterval(f , 50); }); /* on mouseleave of the whole <li> the scrollable area is hidden */ $('#menu li').bind('mouseleave',function () { var $this = $(this); clearTimeout(stacktime); $this.find('.sc_menu') .css('visibility','hidden') .find('a') .css('visibility','hidden'); $this.find('.sc_menu_wrapper') .css('visibility','hidden'); }); /* when hovering a thumb, change its opacity */ $('.sc_menu a').hover( function () { var $this = $(this); $this.find('img') .stop() .animate({'opacity':'1.0'},400); }, function () { var $this = $(this); $this.find('img') .stop() .animate({'opacity':'0.3'},400); } ); });
And that’s it! Enjoy!
wow! pure amazing. it seem to be so flexible, what make it good for so many web design purposes. thanks for sharing.
nice effect! found a lot of good ideas for navigation on your blog so far. keep it up! thanks for sharing
awesome…ugh!!!
really Awesome….
Its’s working fine alone atmosphere but when i have try to set with any site then this plugin Slide area or all area any Menu link or any other link not working my mean Its slide out top area so any other link with site not working can you check it and give solution for it.
congrats, right know you are the most inspiring website out there!
What would I need to change in the javascript if I wanted the navigation to be at the top of the page and for the slider to start at the top and work it’s way down? And the tutorials on the site are the best I’ve seen yet.
Add this code above “$wrapper.bind(‘mousemove’,function(e){ ”
var wrapperHeight = $wrapper.height();
var menuHeight = $menu.outerHeight() + 2 * inactiveMargin;
var top = (0) * (menuHeight – wrapperHeight) / wrapperHeight – inactiveMargin;
$wrapper.scrollTop(top+10);
What an amazing result and great tutorial – thank you so much.
I see someone has figured out the javascript of how to do it from the top – does anyone have any ideas about how to have the thumbs shoot out from the left hand side?
Thank you!
Thanks Kamalino!
@Meera, the thumb containers need to be shown and hidden by using “visibility”. That means that the containers are laid over any other content that is in that area. I recommend using this effect as it is shown in the example or try to change the code and use the display property instead. Hope it helps, cheers, ML
Awesome Tutorial!!!!! I gotta say this website has the latest content out there. You guys aren’t afraid of posting stuff!!!!! Just great.
Mary Lou, having same issue I have with the “Fixed Fade Out Menu” For some reason I can’t get the thumbs to scroll on the iPad. Your code lends itself so well to smaller devices so I hope you can figure this out.
Great job!
Exactly what I was looking. One concern though – If the total height of the images is less than the screen height the images appears from top leaving a gap from the last image and the image menu. How can I make it appear from the top of the image menu?
Thanks!
How can i do the same in horizontal scroll??
Thanks for all its great¡¡
its very nice one for developers..
thanks for this tutorial posting
Wow this is really good. Thank you very much for sharing.
So fantastic and i neva thought i could get something like this for free.
Hi can i please have the codes of just the thumbnails scroller without the menu bar?
really nice, very useful! But how can i center the menu, it only works alligned left?
ok first of all you a great developer and i enjoy reading your articles and you tutorials.
is it possible to make the image appear in the background once we click the thumbnail ?
Thankyou very much for this menu.
I have a question. I want to put the link button in my menu. But the menu is in (ul class=”menu” id=”menu”)
(a href= “abcd”)
My question is . i want to put this “abcd” link in my own ul sub menu.
Kindly inform me how to do this.
For example my menu are like this.
HOME
———>>> SUB MENU
——————————>>>> i need abcd here
Kindly inform me.
Take care Thankyou once again for this beautiful menu
SOMEBODY PLEASE HELP ON THIS ISSUE PLEASE!
Thankyou very much for this menu.
I have a question. I want to put the link button in my menu. But the menu is in (ul class=”menu” id=”menu”)
(a href= “abcd”)
My question is . i want to put this “abcd” link in my own ul sub menu.
Kindly inform me how to do this.
For example my menu are like this.
HOME
———>>> SUB MENU
——————————>>>> i need abcd here
Kindly inform me.
Take care Thankyou once again for this beautiful menu