Scrollable Thumbs Menu with jQuery

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 […]
scrollableThumbs

From our sponsor: Market smarter with Mailchimp's automated messaging tools.

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!

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!

Message from TestkingThe CISA tutorials for beginner as well as advance users really help to learn how to create excellent jquery plugins to enhance website functionality. Download the CISM tutorials and other resources to pass cissp certification exam and become expert.

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 23

Comments are closed.
  1. wow! pure amazing. it seem to be so flexible, what make it good for so many web design purposes. thanks for sharing.

  2. nice effect! found a lot of good ideas for navigation on your blog so far. keep it up! thanks for sharing

  3. 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.

  4. 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.

  5. 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);

  6. 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!

  7. @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

  8. Awesome Tutorial!!!!! I gotta say this website has the latest content out there. You guys aren’t afraid of posting stuff!!!!! Just great.

  9. 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.

  10. 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!

  11. Hi can i please have the codes of just the thumbnails scroller without the menu bar?

  12. really nice, very useful! But how can i center the menu, it only works alligned left?