Create a Vertical, Horizontal and Diagonal Sliding Content Website with jQuery

Written by Kevin Liew on 14 Jul 2009
709,867 Views • Tutorials

Introduction

Content Sliding website is one of the famous and creative design techniques for portfolio website. One thing, please make sure you put the menu on every single page to avoid confusion/dizziness.

  • You should put the navigation menu in every single page
  • Or, fix the position of the menu
  • Let your visitors know exactly what section they're reading, like highlight the selected menu item and have a clear title

In this tutorial, we will learn to scroll your web content vertically, horizontally and plus diagonally! Don't worry, we won't rely on javascript too much, we will use css/html for the layout and javascript only do the scrolling. And hey, it will still work even if your browser doesn't support javascript.

And, thanks to Ariel Flesler, his scrollTo plugin is simply amazing!

Advertisement

1. HTML

Depend on which direction you want to scroll your website, each of them have slightly different layout. For the horizontal and vertical, they use the same layout, whereas for diagonal, you have to add extra div to create the "diagonal". It sounds like a dirty trick, but hey, it works! :)

I put <a name="name"></a>, just in case some of the browsers out there don't support javascript.

Structure for jQuery share it toolbox

Scroll Horizontally & Vertically

<div id="wrapper">
	<div id="mask">

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a> | 
				<a href="#item4" class="panel">4</a> | 
				<a href="#item5" class="panel">5</a>
			</div>
		</div>
		
		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>

		<div id="item4" class="item">
			<a name="item4"></a>
			<div class="content">item4 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item5" class="item">
			<a name="item5"></a>
			<div class="content">item5 <a href="#item1" class="panel">back</a></div>
		</div>

	</div>
</div>

<div id="wrapper">
	<div id="mask">

		<!-- first row -->

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a>
			</div>
		</div>
		
		<div class="item"></div>
		<div class="item"></div>
		<div class="clear"></div>

		<!-- second row -->		
		
		<div class="item"></div>

		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>

		<div class="item"></div>
		<div class="clear"></div>
		
		<!-- third row -->

		<div class="item"></div>
		<div class="item"></div>

		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div class="clear"></div>

	</div>
</div>
<div id="wrapper">
	<div id="mask">

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a> | 
				<a href="#item4" class="panel">4</a> | 
				<a href="#item5" class="panel">5</a>
			</div>
		</div>
		
		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>

		<div id="item4" class="item">
			<a name="item4"></a>
			<div class="content">item4 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item5" class="item">
			<a name="item5"></a>
			<div class="content">item5 <a href="#item1" class="panel">back</a></div>
		</div>

	</div>
</div>

<div id="wrapper">
	<div id="mask">

		<!-- first row -->

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a>
			</div>
		</div>
		
		<div class="item"></div>
		<div class="item"></div>
		<div class="clear"></div>

		<!-- second row -->		
		
		<div class="item"></div>

		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>

		<div class="item"></div>
		<div class="clear"></div>
		
		<!-- third row -->

		<div class="item"></div>
		<div class="item"></div>

		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div class="clear"></div>

	</div>
</div>

Scroll Diagonally

<div id="wrapper">
	<div id="mask">

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a> | 
				<a href="#item4" class="panel">4</a> | 
				<a href="#item5" class="panel">5</a>
			</div>
		</div>
		
		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>

		<div id="item4" class="item">
			<a name="item4"></a>
			<div class="content">item4 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item5" class="item">
			<a name="item5"></a>
			<div class="content">item5 <a href="#item1" class="panel">back</a></div>
		</div>

	</div>
</div>

<div id="wrapper">
	<div id="mask">

		<!-- first row -->

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a>
			</div>
		</div>
		
		<div class="item"></div>
		<div class="item"></div>
		<div class="clear"></div>

		<!-- second row -->		
		
		<div class="item"></div>

		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>

		<div class="item"></div>
		<div class="clear"></div>
		
		<!-- third row -->

		<div class="item"></div>
		<div class="item"></div>

		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div class="clear"></div>

	</div>
</div>
<div id="wrapper">
	<div id="mask">

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a> | 
				<a href="#item4" class="panel">4</a> | 
				<a href="#item5" class="panel">5</a>
			</div>
		</div>
		
		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>

		<div id="item4" class="item">
			<a name="item4"></a>
			<div class="content">item4 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div id="item5" class="item">
			<a name="item5"></a>
			<div class="content">item5 <a href="#item1" class="panel">back</a></div>
		</div>

	</div>
</div>

<div id="wrapper">
	<div id="mask">

		<!-- first row -->

		<div id="item1" class="item">
			<a name="item1"></a>
			<div class="content">item1 
				<a href="#item1" class="panel">1</a> | 
				<a href="#item2" class="panel">2</a> | 
				<a href="#item3" class="panel">3</a>
			</div>
		</div>
		
		<div class="item"></div>
		<div class="item"></div>
		<div class="clear"></div>

		<!-- second row -->		
		
		<div class="item"></div>

		<div id="item2" class="item">
			<a name="item2"></a>
			<div class="content">item2 <a href="#item1" class="panel">back</a></div>
		</div>

		<div class="item"></div>
		<div class="clear"></div>
		
		<!-- third row -->

		<div class="item"></div>
		<div class="item"></div>

		<div id="item3" class="item">
			<a name="item3"></a>
			<div class="content">item3 <a href="#item1" class="panel">back</a></div>
		</div>
		
		<div class="clear"></div>

	</div>
</div>

2. CSS

The CSS is basically almost the same with the tabbed based content slider tutorial. I have illustrated how it works in that tutorial, so you might wanna check that out as well.

Scroll Horizontally & Diagonally

 

  • #mask : height=100%, width = 100% * total of items
  • .item : height=100%, width = 100% / total of items
body {
	height:100%;
	width:100%;
	margin:0;padding:0;
}

#wrapper {
	width:100%;
	height:100%;
	position:absolute;
	top:0;left:0;
	background-color:#ccc;
	overflow:hidden;
}

	#mask {
		width:500%;
		height:100%;

		background-color:#eee;
	}

	.item {
		width:20%;
		height:100%;
		float:left;
		background-color:#ddd;
	}
	
	
	.content {
		width:400px;
		height:300px;
		top:20%;
		margin:0 auto;
		background-color:#aaa;
		position:relative;
	}
	
	.selected {
		background:#fff;
		font-weight:700;
	}

	.clear {
		clear:both;
	}

Scroll Vertically

The width and height are opposite from scrolling horizontally. Calculations are:

  • #mask : width=100%, height = 100% * total of items
  • .item : width=100%, height = 100% / total of items
	#mask {
		width:100%;
		height:500%;
		background-color:#eee;
	}

	.item {
		width:100%;
		height:20%;
		float:left;
		background-color:#ddd;
	}

3. Javascript

So, you must be thinking how complicated the javascript would be. You'll be surprise! its only a line of code to make the scrolling effect. Thanks to jquery.scrollTo Plugin. What we have to do is solve the layout using css/html, and the plugin will do the rest.

$(document).ready(function() {

	//get all link with class panel
	$('a.panel').click(function () {

                //reset and highlight the clicked link
		$('a.panel').removeClass('selected');
		$(this).addClass('selected');
		
		//grab the current item, to be used in resize function
		current = $(this);
		
                //scroll it to the destination
		$('#wrapper').scrollTo($(this).attr('href'), 800);		
		
                //cancel the link default behavior
		return false;
	});


	//resize all the items according to the new browser size
	$(window).resize(function () {
		
		//call the resizePanel function
		resizePanel();
	});
	
});

This resize function have 2 versions. One for vertical and another for both horizontal and diagonal. The only difference is the mask_height and mask_width.

Vertical
function resizePanel() {

	//get the browser width and height
	width = $(window).width();
	height = $(window).height();

	//get the mask height: height * total of items
	mask_height = height * $('.item').length;
		
	//set the dimension		
	$('#wrapper, .item').css({width: width, height: height});
	$('#mask').css({width: width, height: mask_height});

	//if the item is displayed incorrectly, set it to the corrent pos
	$('#wrapper').scrollTo($('a.selected').attr('href'), 0);
		
}
Horizontal & Diagonal
function resizePanel() {

	//get the browser width and height
	width = $(window).width();
	height = $(window).height();

	//get the mask width: width * total of items
	mask_width = width * $('.item').length;
		
	//set the dimension	
	$('#wrapper, .item').css({width: width, height: height});
	$('#mask').css({width: mask_width, height: height});
	
	//if the item is displayed incorrectly, set it to the corrent pos
	$('#wrapper').scrollTo($('a.selected').attr('href'), 0);
		
}

Conclusion

That's it, simple and easy! I hope you all will enjoy 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. You can subscribe to my RSS for more jQuery tutorial posts! Or go to my website footer to follow me on twitter, and buy me a drink! Thanks!

Jump to Certain Item on Page Load

This is one of the most popular request. A lot of people want this content slider to display certain item on page load. It's simple, you need to use this:

$(document).ready(function () {

   $('#wrapper').scrollTo('ITEM-ID-HERE', 0); 

   ......
   ......
   ...... 
}

With that line of code, the slider will jump to the item on page load.

Update

31 Aug 2009 : Due to popular demand, and something I should have created. I have added window resize function.
Demo 1Demo 2Demo 3Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

792 comments
Dante 15 years ago
Sorry, I have another question.
How would I go about increasing the distance between the content divs while still keeping them centered?
Thanks
Reply
Dante 15 years ago
Thanks for your reply below by the way. I appreciate you taking the time to help me (and everyone else) out.
I find that if I increase the width of .item any larger than 33% the 3x3 grid structure breaks. I was using .content top: 5% to keep it centered which was working pretty well.
So I had .item {width:33%; height:400%;}
.content {width:875px; height: 500px; top:5%; left: -20%;}
But anything larger than this and the divs end up all over the place.
Thanks again!
Reply
Kevin Liew Admin 15 years ago
yea, because you 3x3 grid will be 100% / 3... so 33% is correct...

#wrapper is 100%... which will be the width of the browser,
and then, the mask is 300% of the #wrapper, (3x3.. 3 item in a row, so 100% x 3)..

and the content recommended to be the same width or smaller than .item div.. because .content is a child of .item.. if it's larger than its parent, it will break the grid.
Reply
Dante 15 years ago
Thanks for the reply. I managed to get it working in the end with similar settings to what you were suggesting.
This script is awesome by the way. It works so much more efficiently than the other versions I have tried. Nic work
Reply
Kevin Liew Admin 15 years ago
I'm glad you like it :) Thanks! I will make another version of this just to redo it in a more efficient way.
Reply
Ronald 15 years ago
hello kevin,
I applied the script to my site but the scrolling effect doesnt work :(
i have <tr> inside the <div>, will this be a reason?
Reply
Kevin Liew Admin 15 years ago
I don't think that the reason. What I would suggest, grab the demo / working version and start building your website by adding your html codes.
Reply
Phura 15 years ago
This is a very useful tutorial really, thanks for the tut once again
Reply
Shauna-Kay 15 years ago
Hey. I have used this layout before and I got the highest in my class! I want to use it again for a new site. What I want to know is, does this come with an automatic scrollbar if my info gets to long?
Reply
Kevin Liew Admin 15 years ago
erm, no... but you will have to create another div to wrap around your info, and set it overflow:auto & a fixed height... it should show the scrollbar if it gets too long.
Reply
AP 15 years ago
So when you say wrap a div around the info, are you referring to the div with class "item"?
Reply
Shauna 15 years ago
Hi again...
Soo I just have a little query. How do you actually highlight the menu tab that is selected when it is selected so that when I am on the page I can clearly see which one I am on? Maybe I missed that part.
Thankies
Reply
Kevin Liew Admin 15 years ago
this one is easy... each time you selected a menu item, it attached a class called "selected".. you just have to style the class.
Reply
Shauna 15 years ago
Hi Kevin
So I created a scroll bar. Now I want the scrollbar to be fixed, because when its scrolling horizontally, the scrollbar scrolls too and it looks a bit untidy. What should I do?
Reply
Kevin Liew Admin 15 years ago
hmm, there isnt anyway unless you hide the scrollbar... hide and show scrollbar can be quite annoying because it reduce the height and width of your webpage.. and cause it "jumping"....
Reply
Jackson 15 years ago
Hi, thanks for the great tutorial. I keep running into the problem where everything works fine except when I resize the window to a size smaller than the content class and try to navigate to another id. For example: I resize the window on item1 and navigate to item2, item 2 aligns with the window properly to the left, but item1 overflows into item2 overlapping on the left. Not sure if I've described it well enough, but hope that there's a way to fix this.
Reply
Kevin Liew Admin 15 years ago
weird, it doesn't happen to me... what browser are you using?
Reply
Jackson 15 years ago
Hi Kevin,

I forgot to clarify that the reason why I'm seeing overlap is because the background images on my divs are transparent, if you set the opacity of your content divs to say .40, and then increased the content width to around 700px, it will be very obvious what the overlap is. If you have a solution to that, that would be really great, but if not, I can still live with it, and either way, thanks for the great tutorial.
Reply
Omid 15 years ago
Hi,
how can I start the horizontal slider at item3 for example. I don't wanna start at item1, because I'd like to start at item3 and then jump to left and right.

Is that possible?
Thx!
Reply
Kevin Liew Admin 15 years ago
Just put this on window load:

$('#wrapper').scrollTo('#item3'), 0);
Reply
Jackson 15 years ago
Kevin: I think you meant $('#wrapper').scrollTo('#item3', 0); you had an extra parentheses after #item3, also, this is exactly like what I'm doing now, and I'm also running into a problem with this.

If you resize your window right after the page loads, all of the items divs will move to the left, messing up the position. However, if the page loads and instead of immediately resizing the window you first click on a link to scroll to another page, and then attempt to resize the window, everything will work just fine. In the case of Firefox 4 on my mac and IE9 on windows, which I've tested respectively, resizing right after it loads to the desired starting div actually results in jumping back to the first item div. Sorry for raising so many questions/problems. Thanks for the great tutorial again!
Reply
Jason 15 years ago
Hey,

Forgive me for my ignorance but where would this code be inserted?
"Just put this on window load:" is over my head as I'm not at all versed in this. Thanks for you consideration to all who made this possible.
Reply
Francesco 15 years ago
Any idea about it, I want to do the same thing
Reply
Daric Christian 15 years ago
Great tutorial thanks - here is my question - I have the horizontal site working, but I want to make a fixed next button which will just go to the next section - I thought I could use the anchors to do this using something like - $(this).next(); - but I am having trouble, also want to make sure the scrollto script is called on the link - any ideas?
Reply
Kevin Liew Admin 15 years ago
you need to get the sibling of current selected item. Currently selected item link has a class called "selected"... maybe you can get the next sibling of the selected element...
Reply
Daric Christian 15 years ago
What exactly does this line in your script return : current = $(this);
Reply
Daric Christian 15 years ago
Ok - I got this to work with one issue - it does not trigger the class to activate the scrollTo - it just jumps to the anchor any ideas?? Thanks again for your time.


var max = 8; //number of sections

function goToNext() {

var hash = String(document.location.hash);
var newh = Number(hash.replace("#item",""));
(newh > max-1) ? newh = 0 : void(null);
document.location.hash = "#item" + String(newh+1);

}

<a href="#" class="panel" onclick="goToNext(); return false;">link</a>
Reply
Kevin Liew Admin 15 years ago
ar, because you use the hash tag, you need to use scrollTo:

$('#wrapper').scrollTo($( '#item' + String(newh+1) ), 800);
Reply
Daric Christian 15 years ago
of course I do - thks again for the info and the tutorial
Reply
michael western 15 years ago
Hey Daric/Kevin - Thanks so much Kevin for the Great Script.

I am also trying to incorporate prev/next buttons. I can't seem to get it to work. Would you mind writing the complete script with correction so I can see how it looks.

Thanks in advance.
Reply
michael western 15 years ago
Sorry I should have been more clear. It is fixed prev/next buttons I am trying to create.

Thanks.
Reply
kevin 15 years ago
Michael did you find a method to do this?
Reply
Rod 15 years ago
Hi people, first very thanks for the awesome tutorial and sorry for my english.

I followed the tutorial and I got some amazing results, my idea is a page that is lying down and changing the section to this effect. My problem comes when the horizontal scroll, items (item1, item2) have different heights. All items remain the same height, resulting in that if an item has a smaller high because the content is less, this item is extended to match the other creating a empty space and meaningless.

My question is whether there is any way to customize items, each with its height but not disable the vertical scroll. I tried to create different types of items but have not obtained results. Any suggestions or help is welcomed and appreciated to infinity.

Thank you very much everybody.
Reply
Rod 15 years ago
Hello again, sorry for the insistence, I'll add some data and put the files that I have now to see if it is more clear my problem (I think yesterday I explained too bad)

My test file has not changed practically nothing except some parts of css code. In wrapper, I just placed an overflow-y: auto; overflow-x: hidden; to maintain the feeling of sliding horizontal and vertical scroll to perform.

The next change is just the item .content, where I placed a width of 1024px and a height of 4000px, and I removed the top placement 20% to simulate a traditional page with the sliding effect on change section.

The third and final change is to duolicate .content (.content2) to create a little height (2000 px) to simulate a page with less content (in this case, item 5)

Here the files to have a more realistic view. If you visualize the page in the browser (in my case Safari 5.1) when moves to item5 (black) and when you go down a completely empty space is filled to equal in height to the other .content (4000px). My question is if we can solve this problem and that the scroll ends when it should end (in this case, .content to 4000px in .content 2 to 2000px, and so with each if must be different)

Thank you so much

http://www.megaupload.com/?d=RVWC19OG
Reply
Tosh 15 years ago
Hi there Kevin,
my apologies if you've already gone into this but I have maybe a silly question...

I have followed this tut and have managed to get it rolling successfully in a manner..

Example..
http://contagiouscreative.co.uk/salomon/test/sfp_blacknav.html

You'll see that when clicking on one to 5 or the 1st to the 5th menu item at the top, things appear to work fine.

When clicking the 6th you can see the funny scrolling caused because the 6th item that I've added is dropping down a line due to a width that im not adjusting somewhere.

It would be great if you could point me in the right direction as this would help me to fully understand whats going on.

Thanks in advance.




Reply
Kevin Liew Admin 15 years ago
i see what you mean, the last item must have dropped to the bottom because there isn't enough width to fit it in. do this calculation:

#mask : width = 100% * total of items
.item : width = 100% / total of items
Reply
Camata 15 years ago
Hello Thanks the tutorial worked great, my only problem is i have rollover links in css in a class where you have "panel" how can i get my rollover links to work and keep the links in the panel class?
Reply
Kevin Liew Admin 15 years ago
i don't understand what you mean. do you mean you want to use rollover link to replace all those panel links? if yes, just add the panel class to your rollover links and replace the href accordingly.
Reply
Camata 15 years ago
Thanks for replying, yea i did not explain that well, but i realized that i could assign multiple classes to each element so that what i did and my rollovers worked great. But i have another issue i want to add page six but it keeps going to item 5 , any help will be appreciated. Thanks
Reply
Kevin Liew Admin 15 years ago
make sure you have correct classes and id for each item. it should work fine.

menu link:
<a href="#item6" class="panel">6</a>

new item:
<div id="item6" class="item">
<a name="item6"></a>
<div class="content">item6 <a href="#item1" class="panel">back</a></div>
</div>
Reply
Plog 15 years ago
resize error "targ is null" in jquery.scrollTo in ie
Reply