Parallax Scroll Effect

Parallax Scroll Effect

Parallax scrolling, an effect that allows sections of a website to scroll at different speeds, is an effect that has gone through various stages of popularity over the last few years. I’m not going to debate the usefulness or trendiness of parallax scrolling here, I’m simply going to show you how to do it.

There’s a popular plugin called parallax.js that can quickly and easily take care of your parallax needs if you choose to use it. However, this plugin has a lot of features you might not use, and we can get the core functionality of parallax in about 100 bytes if we write our own code (down from 11 KB). All you need is a a containing element, a contained element with a background image, and a few lines of jQuery.

Goals

Create a simple parallax effect using CSS and JavaScript and no plugins.

View the Demo

See the Pen Parallax Scroll Effect by Tania (@taniarascia) on CodePen.

Container

We’re going to create a outer element and call it .parallax-container. This class simply sets the height of the parallax window. We’re going to set it to position: relative.

.parallax-container {
  position: relative;
  height: 500px;
}

Image

Now we’re going to create an inner div that will contain the actual parallax background image. The div will be set to position: absolute, which means it will become attached to the nearest relative element (which in this case is the parallax-container).

.parallax {
  position: absolute;
  height: 200%;
  width: 100%;
  z-index: -1;
}

The variable in this class is height: 200% – you can play around with it and make it bigger or smaller depending on how you want the image to look. We have to apply a width: 100% since the element is now absolute. Finally, a negative z-index needs to be set so that the image remains contained to the height of parallax-container.

Content

All HTML layout elements have a transparent background by default. If you choose to use parallax, simply setting your background color on the body element won’t be enough anymore – you’ll have to place all of your non-parallax content inside of elements with a background color. I’m going to create a .content class that simply has a background color so that my content will always appear over the parallax image.

.content {
  background: #fff;
  height: 600px /* This height is only for 
  demonstration purposes since I have no content. 
  It's not necessary for the code to work. */
}

Putting it Together

I’m going to create a top and bottom empty section to create scroll for demonstration purposes.

<section class="content"></section>

On the .parallax div, I edit the style attribute and add a background image.

<section class="parallax-container"> 
  <div class="parallax" style="background: url(image.jpg) center center / cover no-repeat;"></div> 
</section>

The background image will be horizontally and vertically centered in the div, cover the entire div, and not repeat.

Here’s the final HTML:

<section class="content"></section>

<section class="parallax-container">
  <div class="parallax" style="background: url(image.jpg) center center / cover no-repeat;"></div>
</section>

<section class="content"></section>

JavaScript

First, I’m utilizing jQuery, so we’ll link to it.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>

We’re going to create a variable for the parallax class, and count all instances using .length.

var parallaxElements = $('.parallax'),
    parallaxQuantity = parallaxElements.length;
    // more...  

Next, we’ll create a scroll function.

var parallaxElements = $('.parallax'),
    parallaxQuantity = parallaxElements.length;

$(window).on('scroll', function () {
  // more...
});

Let the browser know that we’re going to do an animation with requestAnimationFrame.

var parallaxElements = $('.parallax'),
    parallaxQuantity = parallaxElements.length;

$(window).on('scroll', function () {

  window.requestAnimationFrame(function () {
  // more...
  });

});

Create a for loop, capturing each parallax element in currentElement, and how much has been scrolled with scrolled.

var parallaxElements = $('.parallax'),
    parallaxQuantity = parallaxElements.length;

$(window).on('scroll', function () {

  window.requestAnimationFrame(function () {

    for (var i = 0; i < parallaxQuantity; i++) {
      var currentElement = parallaxElements.eq(i);
      var scrolled = $(window).scrollTop();
      // more...
    }
  });

});

Finally, multiply how much has been scrolled with a negative pixel value, and apply that to the transform: translate3D of the CSS of the individual parallax element.

var parallaxElements = $('.parallax'),
    parallaxQuantity = parallaxElements.length;

$(window).on('scroll', function () {

  window.requestAnimationFrame(function () {

    for (var i = 0; i < parallaxQuantity; i++) {
      var currentElement = parallaxElements.eq(i);
      var scrolled = $(window).scrollTop();

      currentElement.css({
        'transform': 'translate3d(0,' + scrolled * -0.3 + 'px, 0)'
      });
    }
  });

});

Conclusion

Everything that seems complicated can be broken down and simplified. The first time I wanted to use parallax, I used a plugin, but I don’t feel like I learned anything or gained any additional understanding of how it works. Think about any code you might use and not understand, and see if you can create a simplified version of it. In the end, not only will you have learned something, but you’re code will be leaner and faster.

I’m not a fan of including parallax on mobile, so I would add an if statement on the jQuery and a @media query on the CSS to only allow parallax after a certain screen width.

View the Demo

Leave a Reply

Your email address will not be published.

Markdown is enabled in comments. If you would like to post code in your comments, please wrap it in a <pre><code>. HTML/PHP code must be escaped. Failure to do so will make me sad.

Example:

<pre><code>def print_hi(name)
  puts "Hi, #{name}"
end
print_hi("Tania")</code></pre>

9 comments on “Parallax Scroll Effect”

  • David Hager says:

    What is the broswer support using this solution? The original plugin had no mention of browser support either.

  • Anton says:

    Great. I searched for a long time for simple example of parralax and finaly here it is. Thank you.

  • Marcos Gómez says:

    Tania, thanks for the tutorial!

    I just had a doubt, this works with Flexbox?
    Cause im totally in love with it and when I change the display property of the parallax-container all the page breaks.

    Thanks beforehand

  • Keith says:

    Hi Tania
    I’ve just discovered your blog and I love it!

  • Andrea says:

    Hi Tania,
    Works perfectly, thanks for this post and your content.
    I really love how you simplify code.
    Andrea 🙂

  • Ryan says:

    Hi Tania,
    Your blog rocks! I am a self taught web developer in the making and I am greatly inspired by you. I know you spend countless hours behind the scene to produce these amazing articles, Thumbs up for that!

    I have a request, I want to display code in my blog the same way you have done here. Keeping all the font colors as they appear in sublime text etc. I tried prism too but not quite getting there. I cant make them appear in color. And also do you manually put < and > or there is a better and faster way?

    What is the better way to display code, keeping SEO in mind, I can display code with xmp as well. Should i use pre and code with &lt; and &gt; ?

    If you could write a tutorial to get this whole thing working solid the way it is in your blog. I would love that and I am sure most others would love too.

    Please consider.

    Cheers!

    • Tania says:

      Hiya,

      That’s a good idea! And you’re right, there are countless hours of browsing Google and StackOverflow that usually precede one of my articles. 🙂

      In short, I use PrismJS, and I also have code that allows me to paste my code as-is and it will automatically escape properly. I wrap all my snippets in <pre><code class="language-whatever">. So I don’t need to escape HTML, and I don’t need to do anything special after syntax highlighting is set up – just define the language and Prism does the rest. I’ll make a small article about it.

  • Sefhi says:

    Hey Tania, thanks for your work on the blog, I learnt a lot thanks to you ! But it is working the codepen ? I cannot see the effect, only the image on the middle and the title on the top.. maybe isn’t working on chrome, didn’t try on other browser.