“Imagination is everything. It is the preview of life's coming attractions”

- Albert Einstein

  • Simple CSS Parallax Without jQuery


    Simple CSS Parallax Without jQuery

    We all like magic, illusion and stuff like that - especially when something moves and mocks us while doing it while we ask ourselves one question - “How’s that damn thing working?”. Same happens when people encounter CSS parallax, which kinda looks like magic. This simple depth illusion tutorial shows how to make such effect with pure Javascript and CSS.

    CSS parallax is based on z-index manipulation. Using overlapping elements we can create many different illusions. Our goal is to create a simple html document showing an example of CSS parallax based on pure Javascript, just as the above demo shows. Like always, let’s explain everything in steps (for more details check the code comments):

    1. Create an empty html document and put following code between <body> … </body> tags:
      <!-- Helper used to slowly scroll down the document -->
      <a id="scroll-down"></a>
      <!-- Foreground that which "top" style will be adjusted on scroll-->
      <div id="clouds-foreground"></div>
      <!-- Static background-->
      <div id="clouds-background"></div>
      <!-- Some footer for sweet look - optional, no need to add it actually -->
      <div id="footer-bg"></div>
      
    2. Add following styles to your external stylesheet file or put it between <style> … </style> tags in head section of the document:
      /* Our simple scroll helper */
      #scroll-down {
          position: absolute;
          z-index: 200;
          left: 400px;
          display: block;
          top: 300px;
          width: 112px;
          height: 110px;
          background: url('../img/scroll-down.png') no-repeat;
          cursor: pointer;
      }
      
      /* Javascript adjusted foreground */
      #clouds-foreground {
          height: 2300px;
          position: relative;
          z-index: 100;
          width: 750px;
          left: 50%;
          top: 100px;
          margin-left: -375px;
          background: url('../img/clouds1.png');
      }
      
      /* Static background */
      #clouds-background {
          height: 2400px;
          position: absolute;
          top: 0;
          z-index: 50;
          width: 100%;
          width: 750px;
          left: 50%;
          top: -90px;
          margin-left: -375px;
          background: url('../img/clouds2.png');
      }
      
      /* Ah, that tasty footer again.. */
      #footer-bg {
          background: url('../img/bottom-bg.png') repeat-x;
          height: 97px;
          width: 100%;
          z-index: 150;
          top: 100px;
          position: relative;
      }
      
    3. Right now we already have an implemented parallax effect, but to make it a bit more spicy we’ll need to add following javascript in head or just right before </body> closing tag:
      <script type="text/javascript">
          /**
           * Called every 100 miliseconds by an interval to perform ready
           * checks and init the proper code once document is ready
           * 
           * @return void
           */
          function isReady() {
              if (document.readyState === 'complete') {
                  // Check if we're dealing with fancy, retarded
                  // old versions of IE (7-8, no IE 6 support, sorry)
                  var isIe = typeof document.body.attachEvent != 'undefined';
      
                  // Remove ready state check interval
                  clearInterval(readyInterval);
                  // Let's roll
      
                  var cloudsForeground =
                      document.getElementById('clouds-foreground');
                  var scrollDownMarker =
                      document.getElementById('scroll-down');
                  // Save initial clouds and scroll marker position
                  var cloudsForegroundTop = cloudsForeground.offsetTop;
                  var scrollButtonTop = scrollDownMarker.offsetTop;
      
                  // Update bg position in case of loading of a already
                  // scrolled page
                  updateParallax(cloudsForegroundTop, scrollButtonTop);
                  // Attach window on scroll listener
                  window.onscroll = function () {
                      updateParallax(cloudsForegroundTop, scrollButtonTop);
                  }
      
                  // Attach scroll down marker onclick listener
                  // ..first - the IE < 9 check.. god..
                  if (isIe) {
                     scrollDownMarker.attachEvent("onclick",
                         function () {
                             scrollTo(
                                 document.documentElement.scrollHeight
                                     - document.documentElement.clientHeight,
                                 6000
                             )
                         }
                     );
                  // Other browsers - may be replaced by addEventListener()
                  } else {
                      scrollDownMarker.onclick = function () {
                          scrollTo(
                              document.documentElement.scrollHeight
                                  - document.documentElement.clientHeight,
                              6000
                          );
                      }
                  }
              }
      
              /**
               * Updates "parallaxed" elements positions
               *
               * @return void
               */
              function updateParallax() {
                  var scrollY = (isIe) ? document.body.parentElement.scrollTop
                                       : window.scrollY;
      
                  cloudsForeground.style.top =
                      (cloudsForegroundTop - scrollY * 0.25) + 'px';
                  scrollDownMarker.style.top =
                      (scrollButtonTop - scrollY * 4) + 'px';
              }
      
              /**
               * Simple smooth scroll function - scrolls from current
               * window vertical position to "scrollTarget". May have 
               * performance issues on IE - wrote it quickly for 
               * parallax demonstration
               * 
               * @param scrollTarget Int
               * @param duration Int
               * @return void
               */
              function scrollTo(scrollTarget, duration) {
                  var scrollY = (isIe) ? document.body.parentElement.scrollTop
                                       : window.scrollY;
      
                  // Check if this should be the last function call
                  if (duration <= 0) return;
                  var scrollPerTick =
                      (scrollTarget - scrollY) / duration * 10;
      
                  setTimeout(function() {
                      window.scrollTo(
                          scrollY,
                          scrollY + scrollPerTick
                      );
                      scrollTo(scrollTarget, duration - 10);
                  }, 10);
              }
          }
          // Ready check interval
          var readyInterval = setInterval(isReady, 100);
      </script>
      

    Above javascript will adjust top style of #clouds-foreground and #scroll-down on each window scroll event by percent of scroll position value. And that’s all folks!

    Back