Reverse Parallax Effect

Getting started…

This demo requires the use of javascript so please consider your users before implementing this in a professional setting. I haven’t included any graceful degradation, please have a backup plan if the parallax effect is required.

First…

We need to setup a page structure:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml">
<head> 
 
Parallax Background with Javascript and CSS 





</head> 
<body id='background'> 
    
<h1>Parallax Background</h1>

Written by Mike Newell

<h2>Scroll left and right to see the effect</h2>
</body> </html>

This page structure is simple. We include the jquery library from google so users will most likely already have it cached in their browsers. Then we include the stylesheet that will load background images. Finally, we setup a page with some elements inside a container. We’ll write in a script that will grab these elements and make them mobile in the last portion of this tutorial.

Next…

We’ll include a css file to provide a psuedo parallax effect with two background images.

/* 
    Document   : style
    Created on : Apr 3, 2011, 8:28:49 PM
    Author     : Mike Newell
    Description:
        Parallax effect with css background images and elements.
*/
body {
	background-color: white;
	margin: 0;
	padding: 0;
	font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
        background-image: url(../images/bg.gif);
	background-repeat: repeat;
	background-attachment: fixed;
}
#parallax {
	background-image: url(../images/midground.png);
	background-repeat: repeat;
	background-attachment: fixed;
	padding: 5em 0;
        height: 900px;
}
* html #parallax {
	/* because IE6 can't do transparent PNGs for backgrounds */
	background-image: url(../images/midground.png);	
}

#wrap {
    width: 3000px;
}

#content {
    padding: 20px;
    z-index: 999;
    background: black;
    -moz-opacity:0.5;
    opacity: 0.5;
    color: white;
    -moz-border-radius: 250px;
    border-radius: 250px;
    width: 350px;
    height: 260px;
    top: 50%;
    margin-top: -150px;
    position: fixed;
    left: 50%;
    margin-left: -150px;
    padding-top: 90px;
    text-align: center;
}

/*
    GENTEST
*/
.mover {
    z-index: 998;
    background: greenyellow;
    color: white;
    -moz-border-radius: 100px;
    border-radius: 100px;
    position: absolute;
    text-align: center;
}

The base background image is loaded on the body and scrolls with the user scroll on the page. The second background image is a png and overlays the body. This image is loaded in the page #wrap div and moves a bit faster than the underlayer, giving the impression of a parallax. We also style a top layer in a circular div to have some text on the page.

Finally…

We write out a script to grab all the elements with a class of “genTest”.

/*
 *  Written By: Mike Newell
 *  Mike@iwearshorts.com
 *  https://iwearshorts.com/
 *  
 *  No license - Feel free to copy.
 *  
 */
$(window).load(function () {

    var layers = $('.mover').get();
    var layersCount = layers.length;
    var master = [];
    for(var i = 0; i < layersCount; i++) {
       master[i] = {
           speed : 1 - (i / layersCount),
           pos : $(layers[i]).position()
       }

    }

    var top;
    var left;
    var winWidth;
    var docWidth;
    var winHeight;
    var percentLeft;
    var percentTop;
    var absPercent;

    winHeight = $(window).height();
    winWidth = $(window).width();
    docWidth = $(document).width();
    absPercent = (winWidth / docWidth);

   $(window).scroll(function () {

       top = $(this).scrollTop();
       left = $(this).scrollLeft();

       for(var t = 0; t < layersCount; t++) {
           percentLeft = (left / winWidth) * master[t].speed;
           percentTop = (top / winHeight) * master[t].speed;

           var newPositionLeft = master[t].pos.left - (percentLeft * master[t].pos.left);
           var newPositionTop = master[t].pos.top - (percentTop * master[t].pos.top);


           $(layers[t]).css({"left":newPositionLeft, "top":newPositionTop});

       }
   }); 
});

This script grabs all the elements in order and designates a "speed" for each element. Then moves each element according to a percentage based off that speed and the user scroll amount. I deliberately programmed it this way in order to allow user scrolling with mouse wheels and two finger scrolling for mac users. It also works on smartphones, #mobile.

View the Demo. Download the Source.

Inspiration...

Recently I've been building a parallax style website inspired by the lallapalooza site. I had to develop my own little script to move elements based dynamically on how many elements on the page there are. Since we don't have content yet, I won't be able to hard code anything so elements with a certain class must be dynamically included.

6 thoughts on “Reverse Parallax Effect

  1. just wondering if it’s possible to switch it from horizontal scroll to vertical scroll, and what you would need to change to do so?
    Thanks,
    -Jake

  2. Currently using your code to try and build a portfolio for my web design class. Great work! One problem though, any idea why the background loaded onto the body is displaying as white?

  3. Problem solved. The background image in the css was pointing to an image that wasn’t there.

  4. Mike I’m so sorry for not getting back to you the other day. I had a bunch of stuff going on this week and it all blew up in my face. Glad to hear you got it fixed, I haven’t run that script in a while so it would take a second for me to figure out what I was doing anyway…

    Thanks for checking it out!

    Mike

  5. Very cool tutorial, definitely going to bookmark this for future reference.

    I have been wanting to play around with parallex scrolling for a while now.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.