Search code examples
javascripthtmlcsswebparallax

Parallax scrolling: Unwanted gap in between layers


On my website here, I implemented multi-layered parallax scrolling with CSS and Javascript. The page scrolls up and down, and I have 6 layers all moving in parallax. Each layer going back scrolls at a slightly slower speed than the layer in front.

This implementation works until I click on the hamburger menu in the top right corner.

Image of the Bug

I'm not sure why the layers are not stacked on top of each other properly once the slide menu flies out.

Here is the CSS for the parallax scrolling:

.layer {
  background-position: bottom center;
  background-size: auto;
  background-repeat: no-repeat;
  width: 100%;
  height: 800px;
  position: fixed;
  z-index: -1;
}

.layer-bg {
  background-image: url("http://www.reynelee.com/wp-content/uploads/2017/12/layer1.png");
}

.layer-1 {
  background-image: url("http://www.reynelee.com/wp-content/uploads/2017/12/layer2.png\a     ");
  background-position: left bottom;
}

.layer-2 {
  background-image: url("http://www.reynelee.com/wp-content/uploads/2017/12/layer3.png");
}

.layer-3 {
  background-image: url("http://www.reynelee.com/wp-content/uploads/2017/12/layer4.png\a    ");
  background-position: right bottom;
}

And here is the JS:

(function() {
  window.addEventListener('scroll', function(event) {
    var depth, i, layer, layers, len, movement, topDistance, translate3d;
    topDistance = this.pageYOffset;
    layers = document.querySelectorAll("[data-type='parallax']");
    for (i = 0, len = layers.length; i < len; i++) {
      layer = layers[i];
      depth = layer.getAttribute('data-depth');
      movement = -(topDistance * depth);
      translate3d = 'translate3d(0, ' + movement + 'px, 0)';
      layer.style['-webkit-transform'] = translate3d;
      layer.style['-moz-transform'] = translate3d;
      layer.style['-ms-transform'] = translate3d;
      layer.style['-o-transform'] = translate3d;
      layer.style.transform = translate3d;
    }
  });

}).call(this);

HTML:

<div id='hero'>
  <div class='layer-bg layer' data-depth='0.10' data-type='parallax'></div>
  <div class='layer-1 layer' data-depth='0.20' data-type='parallax'></div>
  <div class='layer-2 layer' data-depth='0.50' data-type='parallax'></div>
  <div class='layer-3 layer' data-depth='0.80' data-type='parallax'></div>
  <div class='layer-overlay layer' data-depth='0.85' data-type='parallax'></div>
<!--   <div class='layer-4 layer' data-depth='0.90' data-type='parallax'></div> -->
  <div class='layer-logo layer' data-depth='0.95' data-type='parallax'> <a id='portfolio-button' href="http://www.reynelee.com/my-work/">View Work</a></div> <!-- my logo-->
<!--   <div class='layer-close layer' data-depth='1.00' data-type='parallax'></div> -->

</div>

Solution

  • The problem is caused by the transform css property. For example if you apply the following rule:

    #page {
      transform: translateX(0);
    }
    

    You will notice it causes the same problem without the menu open. I've run into this before and I forget the actual name of the term, but applying transform causes the browser to treat it differently in some way. My recommendation is to apply this translateX(0) on the #page element, and recalculate the positions of your parallax divs based on this default position. I know this is not a complete answer but it should get you going.