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

Written by Kevin Liew on 14 Jul 2009
709,871 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
Nina 15 years ago
Beautiful use of JQuery...Well done!!
I just have a slight problem: I get a JS error in FF saying that F is null.
I noticed on you JS file that the scrollTo function accepts 3 parameters, but only is sent 2. Could that be the problem?
Also, I have another issue that in IE the slides aren't positioned properly. can you help with that too?

Thanks again for your amazing work!
Reply
Kevin Liew Admin 15 years ago
It's fine with two parameters. Does the error generated happen in my demo version?
Reply
Kelly 15 years ago
Hi! Great tut, got it to work well. However I'm wondering if it's possible, for the Horizontal Sliding, to have the vertical scrollbar when there's content overflowing? Here's a site that illustrates what I mean: http://www.incub.ro/

Thanks in advance!
Reply
Kevin Liew Admin 15 years ago
i think you just need to change the value of overflow:hidden
Reply
Nigel 15 years ago
Complete Newbie to this, but would appreciate your assistance in this. I have downloaded the latest zip file and am trying to get 7 items horizontally. I've tried all sorts, changing percentages, but with no success, the items 6 and 7 become diagonal (the other 5 are ok). I guess I should also point out that I've changed the size of the content div to 850px by 550px, although even if I change it back to the original size, items 6 & 7 still act in a diagonal mode...
Can you please assist....
Reply
Nigel 15 years ago
Managed to sort it out myself.....
Reply
Toni Massaar 15 years ago
How did you do it? I'm stuck on the same thingie here! :)
Reply
Kevin Liew Admin 15 years ago
You have to make sure you have set the width of #mask and .item correctly... you can check the layout but disabling the #wrapper overflow to auto, and put border to #mask, .item to see the exact layout. Then tune it accordingly.
Reply
Toni Massaar 15 years ago
hi there... I'm just asking if there's a slight possibility if I could mix up your horizontal sliding website and your background scrolling effect. And what if I want to have a image in front of the background scrolling effect? Amazing tuts by the way, dude! :)
Reply
Kevin Liew Admin 15 years ago
Possible, but I afraid it will be too intensive to slow computer.
Reply
zaza4k 15 years ago
Hey Kevin !
Thanks alot for your work.

Do you know how to center each content ? Margin: 0, auto doesn't work for me :(

Thanks !
Reply
Kevin Liew Admin 15 years ago
Each of the content is already centered.
Reply
stephanie 15 years ago
is it possible to use the vertical code so that it opens from item5 and not item 1
Reply
Kevin Liew Admin 15 years ago
Just put this on window load:

$('#wrapper').scrollTo('#item5'), 0);
Reply
Djaaaay 15 years ago
Hey Kevin,

This is great thanks. I am using the horizontal version and am trying to get the slider to start from item2, but can't seem to get it to work. Any advice would be very helpful.

Here is the code I was using:

$(window).load(function() {
$('#wrapper').scrollTo('#item2'), 0);
});

Thanks
Reply
Dante 15 years ago
Give this a try. I'm not sure if it is the best solution but it works for me.
// Reset all scrollable panes to (0,0) on browser refresh
$('#wrapper').scrollTo( "#item2", { margin: true } );
// Reset the screen to (0,0)
$.scrollTo( "#item2", { margin: true } );
$('#item2').toggleClass('selected');
Reply
MS. 15 years ago
Hi, Kevin!

I'm having a compatibility issue with Vertical Scroll Effect and Lightbox 2. They do not want to work together on the same page. Is there any quick fix to it? Thanks in advance.
Reply
Nigel 15 years ago
Newbie to this... Trying to place a fixed menu over 7 items, have tried using the same width as the items (800px), but it then drops the Contact to the next line, any chance you could have a look at this for me, would really appreciate it.
If it cannot be the same width, can the menu be centered above?
Reply
Nigel 15 years ago
Tosh 15 years ago
Hi there Nigel,
I think i am having the same issue that you may have been.

Actually I am trying to create 6 items but one is dropping down a line and making the line of blocks scroll in a funny way when I click on the 6th option.

It seems like i need to increase a width of something but I just cant work it out :(

Any words of wisdom would be greatly appreciated.

Reply
Jiggs 15 years ago
Hi Kevin,

Properly one the most sillest questions, but if you size-up the width & height of the .content i.e. W:1100 H:1100, then you end up not seeing the remainer of the height content. Is there a css tweak which enables scrolling down to view the missing height content; or would I need to apply an additional jquery plugin like 'jScrollPane' to the .content class (in order to view the missing height content)?

Thanks in advanced and appreciate the tutorial
Reply
Kevin Liew Admin 15 years ago
in the wrapper id, #wrapper change the overflow:hidden to overflow:auto;
Reply
Tam 15 years ago
Hello, first...awesome tutorial. One question...how do I fix my width scrolling so that when resizing my browser window from a full 1920x1200 (screen size) to a small compact say...400x700 something, the content from the left 'item' DOES NOT get "squeezed" or "cropped" into the currently selected 'item.'? This happens with both horizontal (left) and vertical (top) and occurs in provided zip file (after increasing the width larger than default settings). I'm thinking it has something to do with the percentages? Thank you in advance for the solution.
Reply
Ed 15 years ago
Dude, thanks a lot for this tutorial!
Reply
Marc 15 years ago
Thanks for the tutorial, I'm wondering if it's possible to use vertical and horizontal at the same time (I'm tryin to build some kind of grid navigation).

Thanks for your help and awesome tutorial :)

M.
Reply
Kevin Liew Admin 15 years ago
Yes, please have a look at the diagonal layout... instead of filling the content diagonally, you fill the content in all of the items. Don't have to worry about the scrolling part, it will work by default.
Reply
Dante 15 years ago
Sorry about answering a bunch of questions. I was just looking for a solution to my problem and couldn't help myself. My apologies if what I said was wrong.

I'm wondering how you would go about setting a large image as the background of a 3x3 array like you have in the diagonal example. For some reason even if I comment out all the background-colour attributes in the css and set the image as the body background it does not show up. Am I crazy?
Reply
Kevin Liew Admin 15 years ago
for one, i thought someone was spamming.. but then when i look at the comments... they are proper answer! haha :) thanks for helping out.

first, make sure there isn't background color... remove all the background attribute. Set a background color to body, to ensure that... so if you can see the color of your body, it means you have removed them all.

for the large background, I think you need to create another div to wrap around all the items, then set the background on that div. Let me know if it work.

Reply
Dante 15 years ago
That works but I forgot to mention that I would like the background to slide with the content divs.
I figure I could just cut one big image into 9 smaller ones and set them as the item backgrounds but that would need different item classes for each div. There might be a better way but I don't know what it is.
Reply
dav0r 15 years ago
Just asign a big long Bg to your mask. I split up my bg, and made a php-code to assign it, but the problem there is, that on different resolutions the transition won't be smooth.
Reply