The design

Before we even start coding, we need to create our design. If you looked at the end result, then you'll see that I've chosen to play on the theme of Firewatch, and do something a little different with Ice and cool blues.

In whatever program you prefer, create each layer of your illustration and save it as a transparent PNG. Make it wide. I set mine at 1920px in width, and if possible make it something that can be tiled horizontally.

If you plan on supporting Retina displays (@2x resolution) then make the images twice as big, and we’ll scale with CSS later.

For reference, here are my layers:

Layer 1 (logo), Layer 2, Layer 3, Layer 4, Layer 5, Layer 6.

Here’s what my layers look like, all together.

HTML

We will start with a simple template as our base.

Create an index.html file in your favorite text editor, and paste in the following code.

View the HTML: https://gist.github.com/hamstu/57726ec39d110931f548

Notice how we have created a .parallax-layer div for each layer of our illustration, and that they all follow the same pattern.

<div class='parallax-container'>

<div class='parallax-layer layer-0' data-[...]></div>

[...]

</div>

In a moment we will use CSS to add the background-image to each of these layers. Also important are the data- attributes, these will be used in our JavaScript to control the parallax effects. Lower values will move the item slower (so it appears farther away). This is the core principle of the parallax effect.

If you have more or less layers, be sure to add and remove the .parallax-layer divs accordingly, and make sure that layers in the background have lower speed values.

The data-max-scroll attribute is used to stop the layers from scrolling past a specified point. This is important to prevent them from scrolling too much and breaking the effect. You can tweak it later, so don't worry about it too much now.

CSS

The CSS is a little more complex, but still fairly straightforward.

Create a new file called style.css in the same directory as your HTML, and paste in the following CSS.

View the CSS: https://gist.github.com/hamstu/8ba1122b442b367e640e

Let’s break it down now.

Each layer has a lot in common, so we start with a .parallax-layer class (line 12) which sets up some standard styles. You'll notice we give each parallax layer a height of 500px. This height value should be at least as much as the height of your layer graphics, but it could be more. The background images as you can see are attached to the bottom of this div. In my example the net effect is that 500px pushes everything down and makes room for the logo layer to show. Later on you can play with this value and you'll see what I mean.

You'll also notice that .parallax-layer sets position to fixed (line 15). This is very important. Fixed position elements don’t move with the rest of the page content when you scroll. With position: fixed; we can move the layers manually when the user scrolls, and at our own speed, thus creating the lovely parallax effect. We'll detail how to do this in the JavaScript section later on.

One last thing to note about the .parallax-layer is that we're setting a background-size property. This CSS property allows you to specify the width x height of your layer graphic, and since mine are all the same I can just set it once here. I'm actually setting this value to half the actual width and height so that the graphics still looks clear on Retina displays. If you are using your own graphics, you will need to change the background-size width x height to match your images.

For every layer in your design, you'll also need an associated .layer-X class. This class sets up the proper z-index, background-image, and spacing (with the top property) that are specific to that layer.

.layer-2 {

z-index: 5;

background-image: url('...');

top: -50px;

}

You'll need to play around here with the values, the top value in particular, to arrange the layers how you want them to first appear. Be sure you setup the z-index’s correctly too, in ascending value for each layer.

You should be able to preview the page as you write the CSS and tweak things as you go.

You’ll notice that I made some special adjustments to .layer-0. This is my logo layer and since it wasn't wide like the other layers I had to tweak the background-size property and it’s position to get it placed correctly.

Last of all, a note on colors and blending. Your top-most layer (in my case, .layer-5) is going to need to blend/bleed into the content. If you look at the CSS you'll see that I've set a background color on my .content that matches the color of my top-most layer’s graphic. I also set this color as my body’s background-color, just in case. This should prevent any unseemly gaps.

JavaScript

If you did everything right you should have your layers properly stacked and looking nice, but not yet scrolling in any way.

Now create a new file called parallax.js in the same directory as your index.html, and style.css. Paste in the following code.

View the JavaScript: https://gist.github.com/hamstu/925c6fac166c431fe607

I won't go through this code line by line, but in a nutshell it sets up two objects. The first is a ParallaxPart, and the second is a ParallaxManager. At the end of the file you create a new instance of ParallaxManager and pass in the classname of your parallax elements, which in our case is .parallax-layer.

new ParallaxManager('.parallax-layer');

The ParallaxManager object loops through each .parallax-layer and creates a ParallaxPart to represent it. Then whenever the user scrolls, the ParallaxManager sends a message to each Part telling it to update it’s poisiton based on the scroll amount.

If all is well, then adding this code should be the final touch needed to make your parallax effect work!

Two things you may want to change.