Creating a simple parallax scrolling with CSS3 and jQuery

Published Dec 03, 2017Last updated Apr 24, 2018
Creating a simple parallax scrolling with CSS3 and jQuery

As a web developer, you would be asked to do a parallax at some point and there are plenty of plugins out there you can choose from. The problem with these plugins is that some of them are not updated for years, you might want to do some research before considering any of them.

If you don't want to fall into the legacy 'trap', this article shows how you can create a simple solution with CSS3 and jQuery. With CSS3 background-size: cover and background-attachment: fixed, we can create a pure CSS 'pseudo' parallax, for an example and the example from w3schools.

I call them 'pseudo' parallax because they are not quite right as the background is fixed when you scroll up and down the page. To get the right parallax effect, the background should move at the different rate when the foreground moves. There is a technique with CSS transform to achieve a pure CSS parallax, take a look at this tutorial. But I find it difficult to control the layout with this technique, so my solution is to use JavaScript to help me to do two things to make this parallax.

  1. To check if the element is in the viewport:
function isInViewport(node) {
  var rect = node.getBoundingClientRect()
  return (
    (rect.height > 0 || rect.width > 0) &&
    rect.bottom >= 0 &&
    rect.right >= 0 && <= (window.innerHeight || document.documentElement.clientHeight) &&
    rect.left <= (window.innerWidth || document.documentElement.clientWidth)
  1. To calculate the scroll ratio of each element.
$(window).scroll(function() {
  var scrolled = $(window).scrollTop()
  $('.parallax').each(function(index, element) {
    var initY = $(this).offset().top
    var height = $(this).height()
    var endY  = initY + $(this).height()

    // Check if the element is in the viewport.
    var visible = isInViewport(this)
    if(visible) {
      var diff = scrolled - initY
      var ratio = Math.round((diff / height) * 100)
      $(this).css('background-position','center ' + parseInt(-(ratio * 1.5)) + 'px')


The result is only a simple parallax and you have more control over the code and layout. You can see how it works here. You can download the working sample above on GitHub. Let me know what you think and what would be your solutions. Anything suggestions, please leave a comment below. Hope this helps.

Code references

Discover and read more posts from LAU TIAM KOK
get started