Chuck Le Butt
Chuck Le Butt

Reputation: 48758

Smoothing the parallax scrolling of a background image

I've done a bit of research and written a simple bit of jQuery that scrolls the background at a slightly different pace to the foreground, creating a parallaxing effect as you scroll down a website.

Unfortunately it's a bit jerky.

Here's the basic layout of the HMTL:

<body>
    <section>
        Site content goes here.
    </section>
</body>

Here's the CSS:

body {
    background-image: url('../images/bg.png');
    background-repeat: repeat-y;
    background-position: 50% 0;    
}

Here's the JS:

$(window).scroll(function () {
    $("body").css("background-position","50% " + ($(this).scrollTop() / 2) + "px");
});

https://jsfiddle.net/JohnnyWalkerDesign/ksw5a0Lp/

Pretty simple, but my problem is that it's a bit jerky when you scroll, even on a powerful computer.

Is there a way to make the background parallax animate smoothly?

Upvotes: 12

Views: 68224

Answers (6)

Picard
Picard

Reputation: 4102

To make it smooth put the image on a separate div and move the whole element using transform: translate - then you will get really smooth results.

Here is a little example doing something a little bit different but using translate to give you the idea:

HTML:

<div id="wrapper">
     <div id="content">Foreground content</div>
</div>

CSS:

@-webkit-keyframes MOVE-BG {
    0% {
        transform: translate(0%, 0%);
        -webkit-transform: translate(0%, 0%);
    }
    50% { 
        transform: translate(-250px, 0%);
        -webkit-transform: translate(-250px, 0%);
    }
    100% {
        transform: translate(0%, 0%);
        -webkit-transform: translate(0%, 0%);
    }
}

#wrapper {
    width: 300px;
    height: 368px;
    overflow: hidden;  
}
#content {
    width: 550px;
    height: 368px;
    background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
    text-align: center;
    font-size: 26px;
    color: #000;

    -webkit-animation-name: MOVE-BG;
    -webkit-animation-duration: 10s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-iteration-count: infinite;
}

and the fiddle: http://jsfiddle.net/piotku/kbqsLjfL/

from within javascript (using jQuery) you would have to use something like:

$(".element").css("transform", 'translateY(' + ($(this).scrollTop() / 2) + 'px)');

or in vanillaJS:

backgroundElement.style.transform = 'translateY(' + ($(this).scrollTop() / 2) + 'px)';

Upvotes: 1

Shwetha
Shwetha

Reputation: 903

Set the css of the body as below:

body {
  background-image: url(images/bg.jpg); 
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-position: 0 0;
 }

Then using Javascript just get the pageYOffset on page scrolling, and set it to background position of the body background image as below:

window.addEventListener('scroll', doParallax);
function doParallax(){
   var positionY = window.pageYOffset/2;
   document.body.style.backgroundPosition = "0 -" + positionY + "px";
}

Just checkout my post here: http://learnjavascripteasily.blogspot.in/

Upvotes: 5

tuliomarchetto
tuliomarchetto

Reputation: 549

Sometimes we can not use a <img> element inside a div for some reasons like a border-radius may stop working or a width bigger the than parent. I was facing all these issues and the best solution I found was to use:

transition: 0.5s ease;
transform: translate3d(0, 0, 0);

I got really nice and smooth parallax effect using GPU.

Upvotes: 2

rosmcmahon
rosmcmahon

Reputation: 444

Add transition property to your CSS so it can be accelerated by the GPU like this:

body {
    background-image: url('../images/bg.png');
    background-repeat: repeat-y;
    background-position: 50% 0;    
    transition: 0s linear;
    transition-property: background-position;
}

Upvotes: 16

Marc Uberstein
Marc Uberstein

Reputation: 12541

Try changing the .css to .animate. so instead of setting the CSS to hard values you can animate it.

$(window).scroll(function () {
    $("body").animate({"background-position":"50% " + ($(this).scrollTop() / 2) + "px"},{queue:false, duration:500});
});

NB: add script http://snook.ca/technical/jquery-bg/jquery.bgpos.js

Please keep in mind I haven't tested it, let me know if it works.

Animate Background images : http://snook.ca/archives/javascript/jquery-bg-image-animations

Demo: http://snook.ca/technical/jquery-bg/

Upvotes: 0

CherryFlavourPez
CherryFlavourPez

Reputation: 7497

Try animating a property that can be hardware accelerated in browsers that support it. Rather than changing the background-position property, use an absolutely positioned img and then change its position using CSS transforms.

Take a look at stellar.js. That plugin gives you the option of animating using CSS transforms in capable browsers (stellar.js will let you animate background images, with the caveat that it won't work as smoothly on mobile devices). It also makes use of requestAnimationFrame, meaning less CPU, GPU, and memory usage.

If you deem a plugin overkill, you can at least check out the approach taken and adapt it to your needs.

Upvotes: 7

Related Questions