Try Tuts+ Premium, Get Cash Back!
A Simple Parallax Scrolling Technique

A Simple Parallax Scrolling Technique

Tutorial Details
  • Difficulty: Intermediate
  • Completion Time: 20 Minutes

Parallax scrolling is an interesting technique, where, as you scroll, the background images translate slower than the content in the foreground, creating the illusion of 3D depth. As I planned to re-design my personal website, my first goal was to write the shortest and simplest code to achieve maximum awesomeness! I’ll show you how I did it.

In this tutorial, I’ll teach you the simplest parallax scrolling technique you’ve ever came across, so let’s dig in!


Step 1: The Markup

This technique revolves around controlling the speed of background image. So let’s begin with the HTML markup, creating two sections along with the required attributes: "data-type" and "data-speed". Don’t worry; I’ll explain these later.

                <section id="home" data-type="background" data-speed="10">                            
                </section>   
                    
                <section id="about" data-type="background" data-speed="10">
                </section>              
                

I am using the <section> tag with the attributes data-type & data-speed, which were introduced in HTML5. This makes the HTML markup cleaner and easier to read.

According to the specification for Custom Data Attributes, any attribute that starts with data- will be treated as a storage area for private data. Additionally, this won’t affect the layout or presentation.

Since all we need to do is control the speed of the background images, we’ll use data-type="background" and data-speed="10" as key attributes to specify the necessary parameters.

I know what you’re thinking: you’re worried about IE. Never fear; I have a workaround for that too! We’ll discuss it momentarily.

Next, let’s add the content within the <article> tag inside each <section> .

                <section id="home" data-type="background" data-speed="10" class="pages">     
                         <article>I am absolute positioned</article>
                    </section>   
                    
                <section id="about" data-type="background" data-speed="10" class="pages">
                         <article>Simple Parallax Scroll</article>
                </section>              
                

What we’re attempting to do here is making the <section> background scroll slower than its content, i.e <article>. This will help us create a parallax illusion. Before moving on to the jQuery magic, let’s add the background images in our CSS for each <section>.

                                
                #home { 
                background: url(home-bg.jpg) 50% 0 repeat fixed; min-height: 1000px;
                }
                
                #about { 
                background: url(about-bg.jpg) 50% 0 no-repeat min-height: 1000px;  
                }
         

Upon adding backgrounds for both sections, it should look like:

image
image

Let’s add some more CSS to style and spice up the page!

                #home { 
                  background: url(home-bg.jpg) 50% 0 repeat fixed; min-height: 1000px; 
                  height: 1000px; 
                  margin: 0 auto; 
                  width: 100%; 
                  max-width: 1920px; 
                  position: relative; 
                }
                
                #home article { 
                  height: 458px; 
                  position: absolute; 
                  text-align: center; 
                  top: 150px; 
                  width: 100%; 
                }
                
                #about { 
                  background: url(about-bg.jpg) 50% 0 repeat fixed; min-height: 1000px; 
                  height: 1000px; 
                  margin: 0 auto; 
                  width: 100%; 
                  max-width: 1920px; 
                  position: relative; 
                  -webkit-box-shadow: 0 0 50px rgba(0,0,0,0.8);
                  box-shadow: 0 0 50px rgba(0,0,0,0.8);
                }
                
                #about article { 
                  height: 458px; 
                  position: absolute; 
                  text-align: center; 
                  top: 150px; 
                  width: 100%; 
                }
                

Now it should look like this…

image

Step 2: The Magic Code

Yep, that’s right; this is where the magic begins! Using jQuery, we’ll begin with the standard document.ready() method to ensure that the page has loaded and is ready to be manipulated.

                $(document).ready(function(){
                                        
                
                }); 
                

This technique revolves around controlling the speed of the background image that exists in both sections.

Now I need your attention here. The first thing happening below is that we’re iterating over each <section> in the page, which has the atrribute data-type="background".

                $(document).ready(function(){
                
                    $('section[data-type="background"]').each(function(){
                      var $bgobj = $(this); // assigning the object
                    }); 
                
                }); 
                

Add another function, .scroll(), inside .each(), which is invoked as the user begins scrolling.

                $(window).scroll(function() {
                   
                }); 
                

We need to determine how much the user scrolled up, and then divide the value by the data-speed value, mentioned in the markup.

                var yPos = -($window.scrollTop() / $bgobj.data('speed')); 
                

$window.scrollTop(): we are getting the current scroll value from the top. This basically determines how much the user has scrolled up. $bgobj.data('speed') refers to the data-speed assigned in the markup, and yPos is the final value that we need to apply for scrolling. However, it will be a negative value, because we have to move the background in the opposite direction of the user’s scroll.

Let’s investigate a bit more with an example:

image

In the above image, data-speed is 10, and let’s assume that the browser window has scrolled 57px. This means 57px divided by 10 = 5.7px.

                // Put together our final background position
                var coords = '50% '+ yPos + 'px';
                
                // Move the background
                $bgobj.css({ backgroundPosition: coords });
                

The last thing that we need to do is put together our final background position into a variable. In order to keep the horizontal position of the background as static, we’ve assigned 50% as its xPosition. Then, we added yPos as the yPosition, and, finally, assigned the background coordinates to our <section> background: $bgobj.css({ backgroundPosition: coords });.

Your final code might look like:

$(document).ready(function(){
    $('section[data-type="background"]').each(function(){
        var $bgobj = $(this); // assigning the object
    
        $(window).scroll(function() {
            var yPos = -($window.scrollTop() / $bgobj.data('speed')); 
            
            // Put together our final background position
            var coords = '50% '+ yPos + 'px';

            // Move the background
            $bgobj.css({ backgroundPosition: coords });
        }); 
    });    
}); 

Yay, we’ve done it! Try it out for yourself.


IE Fix

There’s one last fix: older IE can’t render the <section> and <article> tags. That’s easy to fix, though; we’ll use the standard solution of creating the elements, which makes the browser magically recognize the HTML5 tags.

                    // Create HTML5 elements for IE
                     
                    document.createElement("article");
                    document.createElement("section");
                

Additionally, we need to use a basic CSS reset file in order to make all the browsers play nicely. Luckily, tools, like HTML5 Boilerplate take care of the brunt of the work for us, when it comes to cross-browser normalizing.


That does it for this lesson! Any questions or notes that you’d like to add? Let me know below!

Tags: parallax
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • S Knowler

    Not sure if this is still ‘Live’ but I have a quick query. First & foremost I have to say I’m NOT a web or CSS Guru BUT I have managed to get this to work with additional elements I’ve added myself. My question is “How do I create a link from one of the .png images?” Can I add a ‘hotspot’ or do I just add a simple html link ‘a href=etc’ where the image is referenced in the style sheet? Sorry but I’m Slightly confused.

  • kfc

    Hi I am trying to get this to work on ie8 but without success, the images arent scaling and the navigational scroll buttons dont work, i have tried using in the head is this correct? It seems to work on most browsers (including ie9) but fails on ie8 (not sure if i have implemented that correctly?) Any ideas?

  • Vojtek

    would this coding style work in dreamweaver?

  • Giancarlo Leonio

    Hi Mohiuddin- thank you for your parallax scrolling tutorial! I compiled a list of some top resources I found around this topic. I included your post. Check it out/ feel free to share. http://www.verious.com/board/Giancarlo-Leonio/implementing-a-parallax-scrolling-effect-in-web-design/ Hope other developers find this useful as well. :)

  • Chris

    hey I’m looking to add multiple sprites but whenever I duplicate and give each sprite their individual styles, only one should show. What am I missing here?

    Any help is greatly appreciated

    Chris

  • http://twitter.com/julieajarrett Julie Jarrett

    this. is. so. dope. helped me learn so much with the demo and source files

    > 1 million props

  • www.codedcontainer.com

    Why is it that I end up with this error in the console log? Anyone else having the same problem? I even copied and pasted your code! $window is not defined.

    • Hlavco

      Replace $window.scrollTop() with $(window).scrollTop()

  • http://www.facebook.com/AndreasOhrlander Andreas Ohrlander

    Hey man! Great tutorial, I have one question though… How the heck do I add another section?
    Would be great if you could reply!

    • Ejaz Siddiqui

      In HTML, Just copy last section, change its ID. Then copy CSS from line 18 to 35. change ID name which you set in last step.

      change background image and intro image in css. Thats it.
      Demo: http://jsbin.com/awecil/2

  • Marcelo Silva

    Sick tutorial man, like this!!!

  • tim

    I don’t under stand the 50% part in the variable coords. Any help?

  • Chaps

    I don’t understand very well position attribute and I’m having a little trouble adding a fixed nav menu on a project like this , can anybody help me please?

  • Mufeed Ahmad

    Like it. thanks for sharing.