Performant Parallaxing

Love it or hate it, parallaxing is here to stay. When used judiciously it can add depth and subtlety to a web app. The problem, however, is that implementing parallaxing in a performant way can be challenging. In this article we’ll discuss a solution that is both performant and, just as importantly, works cross-browser.

TL;DR

  • Don’t use scroll events or background-position to create parallax animations.
  • Use CSS 3D transforms to create a more accurate parallax effect.
  • For Mobile Safari use position: sticky to ensure that the parallax effect gets propagated.

[…]

Both Scott Kellum and Keith Clark have done significant work in the area of using CSS 3D to achieve parallax motion, and the technique they use is effectively this:

  • Set up a containing element to scroll with overflow-y: scroll (and probably overflow-x: hidden).
  • To that same element apply a perspective value, and a perspective-origin set to top left, or 0 0.
  • To the children of that element apply a translation in Z, and scale them back up to provide parallax motion without affecting their size on screen.

The CSS for this approach looks like so:

Code language: CSS

.container {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: scroll;
  perspective: 1px;
  perspective-origin: 0 0;
}
 
.parallax-child {
  transform-origin: 0 0;
  transform: translateZ(-2px) scale(3);
}

Which assumes a snippet of HTML like this:

Code language: HTML

<div class="container”>
  <div class="parallax-child”></div>
</div>