Parallax without Plugins

photo of runners waiting to race down their lanes

We’ve done some simple parallax on a couple of websites recently, using jQuery but no additional JavaScript libraries. It takes some hand-tweaking – and you have to know your items in advance – but is also much lighter weight than a plugin.

The simplest version is elements scrolling independently of the page and each other, for decorative effect – so where they are when isn’t so crucial. Each needs to be fixed position and you’ll likely want some horizontal placement in the form of margins or left/right values.

In the JavaScript we’ll manipulate the CSS top value according to the amount we’ve scrolled the page.

Bind a function to the scroll event, then within that function calculate how far the page has been scrolled and use it to compute a new top value for each parallaxed element. In this case, starting 800px from the top, the element will scroll one quarter as fast as the page itself. The initial value for top in the CSS should also be 800px, or the element will jump when the page is first scrolled (if you are starting with very large – i.e. always offscreen – top values they probably don’t need to match, but there’s also no reason not to match them).

By changing the initial value and the multiplier to how much the page has been scrolled, you can get a variety of rates and entry points. Careful of your opacity – with abstract images, one showing through another can be lovely, but with representative images it may just be weird and distracting.

Multiple Items with Coordination

Since using that version of parallax I was called on to create a more complicated version. In this, we’re scrolling many items separately from the page, but certain subsets of them have to align at points along the way. This made tweaking just starting point and rate of scroll completely impractical – it would have taken forever. It also made screen height an important consideration.

Algebra to the rescue: All of the parallax in this post is linear; that is, the calculation of the CSS top value from the amount the page has been scrolled is the equation of a line. We can make our choice of linear equation more deliberate with two points on the line and the following equation:
 y - y_1 = \frac{y_2 - y_1}{x_2 - x_1} (x - x_1)
In this case, x is the amount of scroll and y is the top value. What are the two points? I used the point where the element should touch the bottom of the screen and the point when all of a batch of elements should be in their proper relative positions. You can get some complicated arithmetic, but fortunately JavaScript knows how to do that. I ended up with a helper function:

Since I had a good number of elements calling this function I expected calculating screen height once and then passing it as a function input was more efficient than calling that jQuery function repeatedly. The function above takes the inputs x1, y1, x2, y2, x, and returns y.

There’s more algebra to determine what the appropriate ending top value should be, dependent of course on number and desired alignment of items. I wanted three rows of items, equally spaced, with margins of 48px above, between, and below. I also wanted them to align that way when the page had been scrolled 1.25 times the screen height – they were “page two” but I needed the breathing room of that extra quarter-screen for the parallax effect.

Why not 3/4 screen height on that third item? Because that gave it far too long to get to its final position, and as a result it took forever to disappear off the top of the screen – long enough to overlap with “page three,” the items lined up when we’d scrolled 2.5 times the screen height. With 7/8 screen height it still lingers, but gets out of the way in time.

Leave a Reply

Your email address will not be published. Required fields are marked *