Register now or login here to start promoting your blog and your favourite articles.
Vertical Scroll Menu with jQuery Tutorial
2 Jun 2009 - 38 Comments
Create a vertical scroll menu that scroll automatically according to your mouse axis-Y movement. This tutorial will cover some jquery tips, tricks, and plugin.
Author: kevin | Source: queness
Demonstration Download

Introduction

Just last week, I came accross to this website Narrow Design. His scroll menu caught a lot of my attentions, I played with it for a while. Yes, unfortunately, it's built in flash. And, Yes, we are going to implement it with jquery - javascript based scroll menu that will do the same thing. Of course, it will not be 100% the same, because some of the fancy features just not that practical to implement with javascript.

So, in this tutorial, we will learn how to create a scroll menu. We will achieve the following objectives:

  • Keep html as simple as possible, and let jQuery and CSS do the rest.
  • Scoll up and down according to mouse-Y axis
  • Use jQuery.color plugin to animate the background-color changes - download jQuery.color
    (Yes, you will need this to animate the background color, I thought it will do it by default, obviously it doesn't! )

Just before we start, let me explain 3 important jquery methods we're going to use:

1. Get mouse axis

The following code will return the X and Y Axis values for your mouse pointer.

<script>
$(document).mousemove(function(e) {
$('#mouse_axis').html("X Axis : " + e.pageX + " | Y Axis " + e.pageY);
});
</script>

<div id="mouse_axis"></div>
2. Get objects offset

The following code will get the offset Top and Left for an object.

<script>
$(document).ready(function() {	
$('#offset').html("Top : " + $('#sidebar').offset().top + " |Left " 
+ $('#sidebar').offset().left);
});
</script>

<div id="offset"></div>

<br/>
<br/>
<br/>
<div id="Sidebar">A Empty DIV named sidebar</div>
3. Get the total of selected elements by the selector.

It will return the total of selected elements.

$('#menu li').length;

Graphical Explanation

Please refer to the following div structure:

Structure for jQuery Scroll Menu

2 main DIVs #sidebar and #menu:

#sidebar : its overflow property is set to hidden. Overflow set to hidden will truncate/hide #menu's extra length and display the #menu according to the width and height of the #sidebar.

#menu : its position property is set to relative. So that if top property set to 0, #menu will snap to the top of #sidebar. So, even with no javascript, you can test the menu with random negative numbers, for example -30px, -100px or -500px. You will able to see the menu is going up. So, jQuery's job is to generate this negative values. To dynamicly generate these values, we will use the mouse-Y, because we want to scroll it up and down. It's quite complicated to explain, but we will walk through it in javascript section.

1. HTML

As usual, we always keep the HTML code as simple as possible. It's good to not mix javascript with html code to increase readibility and tidiness.

The SPAN in this example can be taken out, I put it in just to immitate the menu from Narrow Design.

<div id="sidebar">
<ul id="menu">
<li><a href="#">MENU 1 <span> / 2007</span></a></li>
<li><a href="#">MENU SIZE 2 <span> / 2007</span></a></li>
<li><a href="#">MENU SIZE LONG 3 <span> / 2007</span></a></li>
<li><a href="#">MENU 4 <span> / 2007</span></a></li>
<li><a href="#">MENU SIZE 5 <span> / 2007</span></a></li>
<li><a href="#">MENU SIZE LONG 6 <span> / 2007</span></a></li>
......
......
......
</ul>
</div>

2. CSS

I have played with this CSS for quite a while to achieve the effect I want and tested it with IE as well. I was having this IE problem, where the position:relative and overflow:hidden just won't work the way it should. Fortunately, I found the solution through this website - solution to position relative and overflow in IE. Bingo, it displays exactly the same now.

#sidebar has to set as overflow:hidden to make sure the extra length in the menu is hidden. And the rest is just basic styling for the menu.

body {
padding:0;
margin:0 20px;
}

#sidebar {
height:400px;
overflow:hidden;
position:relative;
background-color:#eee;
}	

#menu {
width:100%;
list-style:none;
padding:0;
margin:0;
top:0;
position:relative;
height:100%;
width:300px;
}

#menu li {
padding:10px 0;
text-align:right;
display:block;
cursor:hand;
cursor:pointer;
}

#menu li a {
background:url() repeat #1f1f1f;
color:#ddd;
font-family:helvetica, arial, verdana;
font-size:9px;
font-weight:900;
display:inline;
padding:20px 8px 5px 20px;
text-decoration:none;
}

#menu li span {
font-family:georgia, arial;
font-size:9px;
color:#464646;
}

3. Javascript

In javascript section, I have separated all the configurable variables on the top of the script. It'll be easier to convert it to a plugin.

The most important part of this script is the last section - generate the top value based on the mouse Y value to allow user to scroll through the entire menu, and won't be affected by the offset of the sidebar as well. The mathematic equation I'm using, it's not the perfect one, but it works. If you have better suggestions, please drop me a message. : )

$(document).ready(function() {	

	//Background color, mouseover and mouseout
	var colorOver = '#31b8da';
	var colorOut = '#1f1f1f';

	//Padding, mouseover
	var padLeft = '20px';
	var padRight = '20px'
	
	//Default Padding
	var defpadLeft = $('#menu li a').css('paddingLeft');
	var defpadRight = $('#menu li a').css('paddingRight');
		
	//Animate the LI on mouse over, mouse out
	$('#menu li').click(function () {	
		//Make LI clickable
		window.location = $(this).find('a').attr('href');
		
	}).mouseover(function (){
		
		//mouse over LI and look for A element for transition
		$(this).find('a')
		.animate( { paddingLeft: padLeft, paddingRight: padRight}, { queue:false, duration:100 } )
		.animate( { backgroundColor: colorOver }, { queue:false, duration:200 });

	}).mouseout(function () {
	
		//mouse oout LI and look for A element and discard the mouse over transition
		$(this).find('a')
		.animate( { paddingLeft: defpadLeft, paddingRight: defpadRight}, { queue:false, duration:100 } )
		.animate( { backgroundColor: colorOut }, { queue:false, duration:200 });
	});	
	
	//Scroll the menu on mouse move above the #sidebar layer
	$('#sidebar').mousemove(function(e) {

		//Sidebar Offset, Top value
		var s_top = parseInt($('#sidebar').offset().top);		
		
		//Sidebar Offset, Bottom value
		var s_bottom = parseInt($('#sidebar').height() + s_top);
	
		//Roughly calculate the height of the menu by multiply height of a single LI with the total of LIs
		var mheight = parseInt($('#menu li').height() * $('#menu li').length);
	
		//I used this coordinate and offset values for debuggin
		$('#debugging_mouse_axis').html("X Axis : " + e.pageX + " | Y Axis " + e.pageY);
		$('#debugging_status').html(Math.round(((s_top - e.pageY)/100) * mheight / 2));
			
		//Calculate the top value
		//This equation is not the perfect, but it 's very close	
		var top_value = Math.round(( (s_top - e.pageY) /100) * mheight / 2)
		
		//Animate the #menu by chaging the top value
		$('#menu').animate({top: top_value}, { queue:false, duration:500});
	});

	
});

Conclusion

That's it. Make sure you check out the demo and download the source code to play with it. Last but not least, I need your support :) If you like this article, please help me to promote it by adding this post into your bookmark. Or you can subscribe to my RSS for more posts. Thanks!

Demonstration Download

Copyright & Usage

The effects and techniques demonstrated in tutorials on Queness can be used in whatever manner you wish without attribution. You cannot copy whole tutorials (unless permission is given), either in English or translated to another language.

Share This Post to Support Me! :)


Comments

Ezrad Lionel on 2 Jun 2009 says:
Wow, I'm very impressed. This menu is really innovative. Say, in a few weeks will you try porting this to Very Versatile Electronic Document VVED? It's almost identical to JQuery, but it's been in development longer and has lots of built in functionailty. Maybe I'll attempt a port then send it to you. Very good job, sir, you should include a menu open transition or something to make me scratch my head and say how'd they do that?? cheers
sonichtml on 3 Jun 2009 says:
Really Cool~~
me on 3 Jun 2009 says:
disable JS, doesn't work - bad times

need to fix this before it could be used in production
Soh on 3 Jun 2009 says:
I think maybe just add overflow hidden in the js so if its disabled, you can still access the menu.

Either way, I think its a great concept and I have learned from this tutorial. Thank you!
Ezrad Lionel on 3 Jun 2009 says:
God damn you graceful degradation psychos.
kevin on 3 Jun 2009 says:
@me, @Soh: yes, declare overflow:hidden in js will do the trick :)...
ryan sandagon on 4 Jun 2009 says:
Nice!

I've done the same menu -- in flash :)
I think adjusting the tweening to make it smoother will help a lot.

Btw, Kevin I'm not sure if you've heard about jQuery Tool. It's a UI library almost similar to the tutorials you've been giving us. You might want to check it here:

http://rsstudioat.blogspot.com/2009/06/jquery-tools-user-interface-component.html
kevin on 4 Jun 2009 says:
@ryan: thanks for the link! well, it's always good and fun to learn how to create it from scratch :)... and it has some benefits, for example, it'd be easier to read our own code than others, and easier to customize as well! :) tho, might have to invest some times and effort on it...
ryan sandagon on 4 Jun 2009 says:
@kevin: Totally agree with you :) It's an added skill and accomplishment too.
mrSeanG on 15 Jun 2009 says:
This is really great.
any chance of a javascript function to automagically get the stage height and then set your containing divs height?

this way you can have a full screen height sized scroller.
I think that paired with a stage.onResize to keep it current in case of a browser resize would be super AWESOME.

I also noticed a small bug: the top item in the UL is REALLY too close to the top and the bottom goes ALL the way up.
The scrolling should really stop before the last item gets past the bottom of the containing item + it's height + a small margin

this way its more congruent to the top item.
kevin on 15 Jun 2009 says:
@mrSeanG: Yes, you can do the full screen scroller. In fact, that was the first version, you have to use jQuery to set the height #sidebar and do it inside onresize event as well.

For the first LI, I, too having some issue with it, can't seem to get the equation right. :(
Cedric Dugas on 18 Jun 2009 says:
Nice, but this is missing a bit of easing, but good work
D. Shun-Luoi Fong on 7 Jul 2009 says:
Would it be possible to change it so that you can do the same thing on a horizontal list of links, i.e. scrolling left/right based on whether you are moving your mouse left/right over the links?
Tony on 29 Jul 2009 says:
I want to begin by thanking you and this is great.

A few issues I have run into:

- I have a need to have close to 100 \menu\s\ and can not scroll down all the way whether I set the sidebar up to 600px (I need this to happen inside of no more than 480px) or keep it at the default of 400px.

- The padding between the menus, with the default settings, does not show up in Safari 4.0.2

Any help with the above would be appreciated.

Thanks again.
WAMPvn on 31 Jul 2009 says:
Good article, thanks!
Ronald H. on 4 Aug 2009 says:
I'll definitely be using this one. I love it and I believe this one will start showing up in more website across the internet in applications like music sites, video sharings sites, and many more projects. How long did it take you to figure this out?
kevin on 4 Aug 2009 says:
@Ronald H: it took me quite a while, when you use it, it has some style issue with safari/chrome, but I think it will an easy fix. And the algorithm I use in this line, doesnt do the job well enough:

var top_value = Math.round(( (s_top - e.pageY) /100) * mheight / 2)
D. Shun-Luoi Fong on 6 Aug 2009 says:
I know I asked this a month ago, but didn\t see any responses. I would still be interested in case anyone has figured out how to do this on a horizontal list of text links. So the list of links would scroll left/right based on whether the user\s mouse is moved to the right/left of the containing box.

Kevin, have you ever given this a shot? any success? Is it even possible to do it this way or will it only work vertically?
fabio on 3 Sep 2009 says:
how I make so that each button is a link with an image will appear in sidebar?

sorry my bad english
ดูหนังฟรี on 7 Sep 2009 says:
Thanks a lot. This article make my better skill.
ฟรี mp3 on 7 Sep 2009 says:
Good article, thanks!
Gallant Promotions on 24 Sep 2009 says:
Your header says this is a horizontal scroll menu, but it seems to be very much vertical... am I missing something here?
NBJK on 26 Sep 2009 says:
hey...could u plz..tell me how to do url redirecting...by some example...
thnks in advance..
That Web Guy on 15 Oct 2009 says:
Am I the only one who thinks this is a usability nightmare? Its not too far distanced from mystery meat navigation.

While its impressive from a technical point of view, this navigation method doesnt belong in any real world scenario I can think of. Its innovation for the sake of innovation.

Kudos for the effort though.
kevin on 15 Oct 2009 says:
Really cool, ill try to adapt it to a Wordpress site cos one has a lot of pages, so could be usefull and pretty fun. Great job!
Nicolas Bonnici on 16 Oct 2009 says:
Thanks for sharing this work!

Good luck

Nico
Webpru on 10 Nov 2009 says:
Very nice tutorial, very helpful, thanks
LuK on 11 Nov 2009 says:
@Everybody, check http://rascarlito.free.fr/hoverscroll/ this is a jQuery Plugin Im using for some time, I also \"abused\" it for sub-navigations and other things, it does more or less the same but I also had the top/bottom issue there...

means you have to be very precise with the cursor to reach the first or last item, this sucks a bit but I found noone who could handle this yet =)...

PS: Your captcha sucks...needed 8 trys!!
Julius Dietz on 4 Dec 2009 says:
Cool menu, one thing that I would really like for it to support though: to react on the middle mouse wheel!

[I can see the inherent difficulties though as its based on the position of the mouse pointer. maybe it would have to be an either mouse position or middle scroll wheel option..?]
Janek on 11 Dec 2009 says:
Awesome script.. i fixed up the top_value formula so it works for any heights etc.

var sidebar_height = $(#sidebar).height();
top_value = Math.round(( ((e.pageY - s_a_top) / sidebar_height * (sidebar_height - mheight))));
nadir on 27 Dec 2009 says:
Dude! This isnt horizontal scrolling! This is vertical scrolling! ... anyway... it seems quite nice and maybe something that I am looking for... Im off to play with it... I actually need the same thing in horizontal scroll actually
nadir on 28 Dec 2009 says:
What do I have to do to make it horizontally scroll!?? means the same thing as shown but rotate it 90 degrees to the right.
Magnus on 8 Jan 2010 says:
This is a vertical menu, not a horizontal one.
dr. Hannibal Lecter on 21 Jan 2010 says:
I was just wondering, how is this in any way horizontal? I see other people asking the same quesion but no answer. So..my advice is: either fix the title or the code. This is misleading.
kevin on 21 Jan 2010 says:
sorry, it was my bad... should have changed it earlier :) it's vertical scroll. I must be sick or something while writting this article... :p
intelphong on 29 Jan 2010 says:
Chào mấy bạn,
Mấy bạn có ví dụ về scroll hình ảnh liên tục nhìn giống như flash, khi mình rê chuột vào một hình ảnh đang chuyển dộng thì nó phóng to lên một tí không?

Nếu có bạn gởi cho mình tham khảo với,

thanks nhiều!!!

http://www.minhsangco.com
jason on 3 Feb 2010 says:
well, i know i'm not alone in asking about horizontal scrolling, so... bump.

what would it take to get it to scroll horizontally?? there are other horizontal scrollers but this one seems to have the smoothest animation effects. and it actually scrolls to the spot where you mouse over, not just jump to it.

thx.

Leave a comment

http://
Subscribe RSS Subscribe RSS, Keep yourself updated with queness latest posts!
Pixel Crayons Buy and Sell Flash Buy and Sell Flash

Buy wholesale computers directly from China at DHgate.com

Discover the tools to build your e-Commerce Site with Netfirms

  •  
  •  
  •  
  •  
  •  

Community News

Recent Comments

Random Posts


View all posts and news Back to top

About the Author

A web designer and developer who is passionate and keen on contributing to the web development industry. Feel free to say hi to me, or follow me on twitter.

Kevin Liew

Partner

  • Web and Designers
  • CSS Style
  • PV.M Garage Blogzine - (Italian)
  • TutsValley
  • Designrfix
  • CoolVibe
  • Web Developer Juice
  • Denbagus
  • Web Hosting Secret Revealed
  • PSD to HTML Conversion
  • BlueHost