Smooth Vertical or Horizontal Page Scrolling with jQuery

In this tutorial we will create a simple smooth scrolling effect with jQuery. We will create a horizontal and a vertical website layout to show the effect. We will be […]

In this tutorial we will create a simple smooth scrolling effect with jQuery. We will create a horizontal and a vertical website layout to show the effect. We will be using the jQuery Easing Plugin and just a few lines of jQuery.

So, let’s start!

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 markup for our example page is going to be very plain. We will have three sections with a heading and a paragraph and am unordered list for the navigation:

<div class="section black" id="section1">
	<h2>Section 1</h2>
	<p>
		MY Spectre around me night and day
		Like a wild beast guards my way;
		My Emanation far within
		Weeps incessantly for my sin.
	</p>
	<ul class="nav">
		<li>1</li>
		<li><a href="#section2">2</a></li>
		<li><a href="#section3">3</a></li>
	</ul>
</div>
<div class="section white" id="section2">
	<h2>Section 2</h2>
	<p>
		A fathomless and boundless deep,
		There we wander, there we weep;
		On the hungry craving wind
		My Spectre follows thee behind.

	</p>
	<ul class="nav">
		<li><a href="#section1">1</a></li>
		<li>2</li>
		<li><a href="#section3">3</a></li>
	</ul>
</div>
<div class="section black" id="section3">
	<h2>Section 3</h2>
	<p>
		He scents thy footsteps in the snow
		Wheresoever thou dost go,
		Thro' the wintry hail and rain.
		When wilt thou return again?

	</p>
	<ul class="nav">
		<li><a href="#section1">1</a></li>
		<li><a href="#section2">2</a></li>
		<li>3</li>
	</ul>
</div>

The HTML is going to be the same for both examples.
Let’s take a look at the style.

The CSS

Since we have two examples, we will start with the horizontal page style.

The main idea is to make the sections very wide and 100% in height. We will add a background image to the bottom right of each section:

*{
    margin:0;
    padding:0;
}
body{
    background:#000;
    font-family:Georgia;
    font-size: 34px;
    font-style: italic;
    letter-spacing:-1px;
    width:12000px;
    position:absolute;
    top:0px;
    left:0px;
    bottom:0px;
}
.section{
    margin:0px;
    bottom:0px;
    width:4000px;
    float:left;
    height:100%;
    text-shadow:1px 1px 2px #f0f0f0;
}
.section h2{
    margin:50px 0px 30px 50px;
}
.section p{
    margin:20px 0px 0px 50px;
    width:600px;
}
.black{
    color:#fff;
    background:#000 url(../images/black.jpg) no-repeat top right;
}
.white{
    color:#000;
    background:#fff url(../images/white.jpg) no-repeat top right;
}
.section ul{
    list-style:none;
    margin:20px 0px 0px 550px;
}
.black ul li{
    float:left;
    padding:5px;
    margin:5px;
    color:#aaa;
}
.black ul li a{
    display:block;
    color:#f0f0f0;
}
.black ul li a:hover{
    text-decoration:none;
    color:#fff;
}
.white ul li{
    float:left;
    padding:5px;
    margin:5px;
    color:#aaa;
}
.white ul li a{
    display:block;
    color:#222;
}
.white ul li a:hover{
    text-decoration:none;
    color:#000;
}

We need to give the body a valid height, because we want to be able to define the height 100% to the section. With positioning the body absolutely and saying top:0px and bottom:0px we stretch the body and give it a height.

The style for the vertical page layout is going to look as follows:

*{
    margin:0;
    padding:0;
}
body{
    background:#000;
    font-family:Georgia;
    font-size: 34px;
    font-style: italic;
    letter-spacing:-1px;
}
.section{
    margin:0px;
    height:4000px;
    width:100%;
    float:left;
    text-shadow:1px 1px 2px #f0f0f0;
}
.section h2{
    margin:50px 0px 30px 50px;
}
.section p{
    margin:20px 0px 0px 50px;
    width:600px;
}
.black{
    color:#fff;
    background:#000 url(../images/black_vert.jpg) repeat-x bottom left;
}
.white{
    color:#000;
    background:#fff url(../images/white_vert.jpg) repeat-x bottom left;
}
.section ul{
    list-style:none;
    margin:20px 0px 0px 550px;
}
.black ul li{
    float:left;
    padding:5px;
    margin:5px;
    color:#aaa;
}
.black ul li a{
    display:block;
    color:#f0f0f0;
}
.black ul li a:hover{
    text-decoration:none;
    color:#fff;
}
.white ul li{
    float:left;
    padding:5px;
    margin:5px;
    color:#aaa;
}
.white ul li a{
    display:block;
    color:#222;
}
.white ul li a:hover{
    text-decoration:none;
    color:#000;
}

Nothing special here, just that we give a big height to the sections. The background image is positioned to the bottom left then.

Let’s add the JavaScript

The JavaScript

The function for the horizontal scrolling effect is the following:

$(function() {
	$('ul.nav a').bind('click',function(event){
		var $anchor = $(this);
		/*
		if you want to use one of the easing effects:
		$('html, body').stop().animate({
			scrollLeft: $($anchor.attr('href')).offset().left
		}, 1500,'easeInOutExpo');
		 */
		$('html, body').stop().animate({
			scrollLeft: $($anchor.attr('href')).offset().left
		}, 1000);
		event.preventDefault();
	});
});

And the function for the vertical scrolling effect is the following:

$(function() {
	$('ul.nav a').bind('click',function(event){
		var $anchor = $(this);

		$('html, body').stop().animate({
			scrollTop: $($anchor.attr('href')).offset().top
		}, 1500,'easeInOutExpo');
		/*
		if you don't want to use the easing effects:
		$('html, body').stop().animate({
			scrollTop: $($anchor.attr('href')).offset().top
		}, 1000);
		*/
		event.preventDefault();
	});
});

You can animate to the respective element by using one of the easing effects. You can see the effect in the vertical demo.
If there is no JavaScript enabled, we still have our good old scroll bars.

Check out the demo, it will lead you to the horizontal page. Here is the direct link to the demo of the vertical page scrolling, or simply click on the link in the horizontal demo.

Message from TestkingUsing testking E20-322 design guide and testking 642-533 live demos, learn how to create effective web applications and themes for your web page. Improve your website accessibility with testking 70-620 web designing course.

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

Fresh news, inspo, code demos, and UI animations—zero fluff, all quality. Make your Mondays and Thursdays creative!

Feedback 212

Comments are closed.
  1. I agree with J. The hash tag would make this perfect. I’ve no idea how to do this though. Any help would be really appreciated. Thanks

  2. This is great… problem is when i recreate the demo (vert) but use gifs as buttons for the navigation (and place these buttons in the reference area) then it navigates but with no animation. Basically, any ideas how the code for the buttons needs to work when said buttons are in the reference area??

  3. To hide the horizontal scrollbar on load add the javascript in your jquery part of your page:

    $(‘html’).css(‘overflow’,’hidden’);

    that way the scrollbar will show for people who do not have javascript enabled and will not for those who have it.

  4. Any ideas how to go about applying an offset to this… so instead of scrolling the content to the top of the browser it leaves an area of padding at the top (the offset amount). Sorry if i have explained this badly!

  5. Firstly, thank you so much for this tutorial. It has been immensely helpful.

    I seem to be having an issue with my implementation. I do not get the easing when scrolling downwards. On my site (which is currently VERY temporary) if I click the img link at the bottom of the page to scroll upwards, it scrolls and eases perfectly (except that it doesn’t seem to go to the VERY top of the page). If I click the “Get in touch!” link at the top of the page, it scroll down and abruptly stops, no easing.

    You can see my temp site at:
    http://www.curtisdulmage.com/resume/resume.html

    Any ideas on how to fix this? I need it to ease smoothly going downwards.

    Thanks again!

  6. problem with opera is solved:
    connect the plugin

    change
    $ (‘html, body’). stop (). animate ({
    scrollLeft: $ ($ anchor.attr (‘href’)). offset (). left
    }, 1000);
    on
    $ (‘html, body’). scrollTo ($ (this). attr (‘href’), 1500);
    everything is ready, the operator is no longer buggy.
    Sorry for the bad english, I’m from Ukraine:)

  7. Fantastic! I am new to web design. . . Only a couple of months in now and I tried implementing it without reading the article. Not one hiccup. Another great article for CODROPS.

  8. Hi all!
    Firstly thank you Mary. Great job.
    I have a question regarding adding sections. I have added a forth section and because of the width issue the added section would display below section1. So, I tried adding more width( but not an extra 4000px) and had no luck… so I subtracted. Width is now set at 3000px and working great… How does that work?
    Thanks again.

  9. @RÓMULO
    The image is static because they are ” #section img{position:fixed} “. Try creating a class ” .right {float:right} ” and add it the actual image in each section.
    EG

    Text goes here …

    PS
    Try creating a “position:fixed” navigation menu and update the links. Great effect.

  10. Hi thanks great work !

    Bur what to do if we want a common background image for the black background pages + a second image, different for each section?
    eg : Section 1 (black) background image: squares + circles
    Section 2 (white) background image: triangles + rectangles
    Section 3 (black) background image: squares + hexagons
    Section 4 white background image: triangles + squares

    Thanks in advance,
    Elsie

  11. Wow exelent code…. !
    I want to implement this code, but I need the result shows it centered, not left. Is it possible?

  12. Hi, this is wonderful, but is there a posibility to make the sections center in the screen instead of aligning them to the left, particularly the second one… I can’t seem to find where is this property… Thanks a lot!!!

  13. I have tried to add a fixed horizontal navigation but because the whole body scrolls, the nav scrolls too. How do I get around this?

  14. Brilliant set of files/tutorial Mary Lou, exactly what I was looking for so a bi thankyou!

    Someone asked previously if there’s any way of slowing down the scroll animation? Possibly to give users more time to see content (images in my case) between screens??? I just wondered if anyone knows how???

  15. Sorry guys, ignore my scrolling speed post, i’ve figured it out!!!!

    Just in case anyone else is wondering how to change the scroll speed…

    In the function code which will be in the main html file (at the bottom starting like this:

    $(function() {
    $(‘ul.nav a’).bind(‘click’,function(event){
    var $anchor = $(this);

    You want to look for the following bit of code:

    1500,’easeInOutExpo’);

    To change the speed you must change the number 1500! Simple as that! Higher number for slower scrolling or lower for faster.

    -Adam

  16. Hi,

    Firstly – thanks Mary for some awesom, easy to impliemnt code!

    I am using it here: http://www.lacarteblanche.com.au/welcome_trans.php

    The problem you will notice is that the sliding animation on first use is very jumpy.

    Can anyone suggest a fix for this? I’ve tried changing the scroll speed as suggested above. I’ve tried pre-loading all the images in a pre-loader before displaying this page (www.lacarteblanche.com.au/load.html). No luck (so its not the heavy images I guess).

    Thanks in advance!
    Lex

  17. For those asking if it’s possible to center align the pages – I have been working on this but can’t find an exact solution.

    I have found a way around it though. I have a fixed nav which sits at the top of the screen and has a centrally aligned container. If you use jquery to get the offset x co-ordinate of the nav (in my case – the h1 that sits at the left) you can then assign this as padding-left for your sections.

    var p = $(‘h1’);
    var offset = p.offset().left;

    $(‘section#serviceHome’).css(‘padding-left’, offset);

    If anyone has a better solution, please let me know,

    Also, to those asking how you can update the address bar, simply add

    window.location.hash = anchor;

    after the animation has finished.

  18. Awesome tutorial. I used parts here:

    http://www.urbankski.co

    Seem to be having a problem with a link not working sometimes on certain browsers, but it’s probably because I really hacked it together poorly to begin + I’m using other jquery on the page.

  19. BEAUTIFUL EFFECT!
    I have been looking for this effect for a long time and I can’t thank you enough for facilitating the ‘js’ and ‘css’ to make it functional.

    A little question -which I think it has to do with my lack on ‘js’:

    I tried to add more div pages from the demo which has 3. I named it #content4. But I am allowed only to manipulate the 3 div pages from the demo to scroll horizontally.

    If you can illuminate me here it would be great.

    Thanks a lot and again GREAT JOB!

    Sincerely,

    Victor

  20. I’ve been working on a CSS based solution for centering/aligning right the images.
    By using percentages and setting the body to something like 1500%, it allows you to create individual sections that are 100% width.
    all you have to do is divide by the number of sections you want to use.
    The math in my case works to be that each section is 7% in width.
    also be sure to count the transitions as sections as well.

    This ends up allowing you to style within each section as a separate page. i.e. floating to the right and centering works as well.

    The downfall is two things. Opera doesn’t support it, and if the user re-sizes the browser it throws off the content. This can be combated by using a fixed with navigation.

    Also, overflow:hidden on the body will destroy the navigation in Google Chrome. so if you are looking for no scroll bars, your boned. at least in chrome, it works with safari, Firefox and IE.

    Check it out, i used the method on my portfolio… and im open to any suggestions as to how i could have done it better.
    http://www.luigiq.com

  21. Looking very good, is there any way of removing the scrollbar(overflow:hidden) AND removing the posibility of scrolling with the use of the middle(wheel)button? Thanks

  22. Thank You soo much!
    Finally smooth that actually is easy to use without major problems.
    I did impemented this and combined with other smoothie:)
    Love it and thumbs up!

  23. Is there a way to start on a middle site… Let me explain what i want to do:

    section 1 = gallery
    section 2 = home
    section 3 = about

    can the starting point be on home instead of gallery?

  24. Yes I was pondering about the same thing as Deived… Must be possible with a ready-function.

  25. Yep, found a way with the “scrollTop”-method:

    $(document).ready(function() {
    $(‘html,body’).scrollTop(0); //0 is the amount of pixels from the top used as offset

    $(‘#navigation ul a’).bind(‘click’,function(event){
    var $anchor = $(this);

    $(‘html,body’).stop().animate({
    scrollTop: $($anchor.attr(‘href’)).offset().top
    },1000,’easeInOutExpo’);

    event.preventDefault();
    });
    });

    So you’d just have to set a certain pixel offset to let the document start with the needed scrolling amount 🙂 !

    Cheers from Germany,

    Benni

  26. Hi mary Lou,

    i’m following your tutorial and i have to say that for someone like me who doesn’t really know anything about coding it is pretty easy…

    The problem is , i am a really noob at this and My Jquery working fine at localhost but when I upload it to http server it doesnot work, i thought i made a mistake but i’ve been trying to upload yours too for a test (didn’t modify anything on it) and it doesn’t work …i mean i cannot click on any link!

    Did i missed something ?

    Hope someone can help me please.
    Thank you

  27. Brilliant! But is there a way to link from an external page? So on home.php, link to products.php#4 and the products.php page loads, then scrolls to the anchor?

  28. I would like to pass a parameter (GET) over sections, is it possible? For example: when a user clicks 2, it goes to #section2 sending a single parameter.

    Thanks in advance

  29. Another query on how to remove the scrollbar as overflow:hidden does not work on IE7 or 8.

    Otherwise awesome tut that i have used on my site.

  30. Hi! good tutorial! Only a question, it’s possible to drag the content ? I talk about an horizontal drag/scroll ….
    Thank you advance..

  31. Hi.
    Thnx for great tutorial.
    One question. How can I get a regular link on the page (not to scroll to as specific position. Say I have a paragraph saying the visitors can contact me. I’d like the words “contact me” to lead the visitors to the contact form section.
    Thnx in advance
    Itsik

  32. Great tutorial. I loved how simple it was and the fact that I was able to modify it to suit my purposes. Thanks for sharing