Search code examples
htmlcsscss-transformsparallaxperspective

Why does translateZ with overflow hidden cause a slight movement to the right?


I was trying to create a parallax effect using pure CSS based on Google's Performant Parallaxing. This involves using perspective, translateZ, and scale. It also involves using a lot of "layers" of PNG images stacked on top of one another. However, there was a problem on those layers.

In this example, only one layer of the PNG image is shown because it is sufficient to show the problem. Here is an image of the problem (a white space on the left side of the div).

Problem

The problem arises in the following situation: the vertical scrollbar of body is visible, the horizontal scrollbar of body is hidden due to overflow, and the parallax-ed image is set to a width of 100%. Strangely, this problem can be solved simply by setting the width of the image to 100vw instead of 100%. Here's the code showing the problem.

html, body {
  margin: 0;
  width: 100%;
  height: 100vh;
  overflow-x: hidden;
}

body {
  perspective: 100px;
}

.background {
  width: 100%;
  height: 101vh;
  background: url('https://i.pinimg.com/originals/13/17/ba/1317ba3fb0901d7b6be59f9c21d39d12.jpg');
  transform: translateZ(-300px) scale(4);
}
<div class="background"></div>

Why does the white space gap appear on the image when its width is 100% and not 100vw?


Solution

  • 100% is respecting the width of the inner window minus the scrollbar (1903px computed width for me) whereas 100vw is respecting the width of the entire viewport with no regard for the scrollbar (1920px computed width for me).

    The reason 100vw 'works' here is because the image is 17px bigger than its counterpart. It also works with 100% width and anything below 100vh height since the scrollbar goes away and 100% is equal to 100vh.

    When you add in the translateZ with a negative value the element you're translating gets visually smaller so the gap you're seeing is a product of that. If you want the image to fill the screen, use a smaller value in your transform or a higher value in scale or width.