Parallax scrolling is something that has been there on the web for quite a few years now, so I assume you are well aware of this effect.

Front-end developers have been using libraries to achieve parallax scrolling. Most of us have started using pure javascript, though. But I think there are still some sites that depend hugely on the libraries like jQuery which of course does our work but is not satisfactory when performance is concerned.

You surely must have come across a landing page which uses parallax scrolling while slowing down the scrolling speed? Doesn’t that feel quite irritating? In this article, we see how we can implement parallax scrolling with nothing but vanilla javascript.

Parallax scrolling effect for Single Element

Let’s do it for single element first. We have the following markup

    ... //Some Header Content
<section class="parallax">
    <h1>LET'S DO IT</h1>

Don’t worry about <header>. It’s there to just illustrate how parallax effect doesn’t begin until the element using it touches the top of viewport i.e. until everything above <section> scrolls out of the viewport.

And then we have following CSS

.parallax {
    background: /** our background image **/;
    background-repeat: no-repeat;
    background-size: cover;

.main h1 {
    text-align: center;
    padding: 15rem 0;
    font-size: 4em;
    color: white;
    background: rgba(29, 25, 29, 0.37);

And now is the turn of Javascript

var parallax= document.querySelector(".parallax");
window.addEventListener("scroll", function() {
    var scrolledHeight= window.pageYOffset,
    limit= parallax.offsetTop+ parallax.offsetHeight;
    if(scrolledHeight > parallax.offsetTop && scrolledHeight <= limit) { (scrolledHeight - parallax.offsetTop) /1.5+ "px";
    else { "0";

We select our parallax element and add scroll event on the window. Then we use pageYOffset property of window to record how much we have vertically scrolled from the top in a variable scrolledHeight*. In case you are dealing with pageYOffset for the first time; here is a demo to illustrate just that

[codepen_embed height=”400″ theme_id=”21620″ slug_hash=”mVmdQK” default_tab=”result” user=”devstreak”]See the Pen <a href=’’>window.pageYOffset Visualization</a> by Devstreak (<a href=’’>@devstreak</a>) on <a href=’’>CodePen</a>.[/codepen_embed]

We update the backgroundPositionY (background-position) of our parallax element to the opposite direction (to bottom) of scrolling as we scroll vertically down. That creates our parallax effect.

Also notice that we subtract the scrolledHeight(window.pageYOffset) by parallax.offsetTop. It is because window.pageYOffset is calculated relative to the viewport. So, to make it relative to our element, we minus it by how much it is far from the top of the viewport. (scrolledHeight - parallax.offsetTop) /1.5+ "px";

But, wait. Why did we divide it by 1.5 there?

We did so to actually slow down the parallax effect. You can change it to any number you desire. While doing all that, we also make sure that background-position doesn’t update until everything above our parallax element is scrolled off the viewport and also that it stops updating when our element has gone out of the viewport.

//evaluates to true only when parallax element
//reaches the top of the viewport and until it is in the viewport.

if(scrolledHeight > parallax.offsetTop && scrolledHeight <= limit)

Finally, here’s the demo of what we have built so far.

[codepen_embed height=”520″ theme_id=”21620″ slug_hash=”Wrjbee” default_tab=”result” user=”devstreak”]See the Pen <a href=’’>Parallax Scrolling with Vanilla Javascript- Single Element</a> by Devstreak (<a href=’’>@devstreak</a>) on <a href=’’>CodePen</a>.[/codepen_embed]

Parallax scrolling effect for Multiple Elements

More than often, we might need to apply parallax scrolling to multiple elements. To do that, we can use the same code making some minor changes.

//helper function
function $$(selector, context) {
    context = context || document;
    var elements = context.querySelectorAll(selector);

window.addEventListener("scroll", function() {
    var scrolledHeight= window.pageYOffset;
    $$(".parallax").forEach(function(el,index,array) {
        var limit= el.offsetTop+ el.offsetHeight;
        if(scrolledHeight > el.offsetTop && scrolledHeight <= limit) {
   (scrolledHeight - el.offsetTop) /1.5+ "px";
        else {

The code above is totally same except that instead of selecting a single parallax element, we selected all elements having .parallax class by making use of a helper function (For the reference see DOM tips to reduce the code size).

And now we can have as many elements running parallax scrolling as we want:

<section class="parallax">
<section class="parallax">
<section class="parallax">
<!-- and so on... -->

Here is the demo for the parallax scrolling effect for Multiple elements

[codepen_embed height=”520″ theme_id=”21620″ slug_hash=”mVmyOv” default_tab=”result” user=”devstreak”]See the Pen <a href=’’>Parallax Scrolling with Vanilla Javascript</a> by Devstreak (<a href=’’>@devstreak</a>) on <a href=’’>CodePen</a>.[/codepen_embed]


Parallax scrolling is being used very widely on the web. While it makes the scrolling beautiful, if used excessively and that too with heavy libraries, the scrolling performance gets hurt which gives users a bad experience.

In fact, it is better not to use parallax scrolling at all if it creates a bad user experience. Today, javascript alone has become so stronger that we don’t need heavy libraries to implement parallax scrolling. So let’s go vanilla!

What do you think about this technique. Do you have a better one? Share your thoughts and comments below.

Share on Facebook Tweet on Twitter Post on Google+ Buffer