100% CSS Parallax Scrolling Effect

The parallax effect has mostly been created using JavaScript. I remember finding JavaScript libraries that could do incredible things years ago.

What is parallax scrolling

Imagine being a passenger in a car going down the freeway, and you look out the window and start to daydream. The trees, buildings, and long stretching fields passing you by. The objects that are closest to you and the road itself go by quickly in a blur, whereas the long fields out in the distance move gracefully and without a hurry. The parallax effect tries to replicate that experience of foreground objects moving faster than their counterparts in the background.

The problem with JavaScript implementations

There are a lot of JavaScript libraries out there that attempt to achieve a similar effect. Unfortunately, for the minimal use cases on the web, they can be implemented poorly, and without performance in mind. These JavaScript implementations would listen to the scroll event and modify elements in the DOM directly. These can cause unnecessary repaints and can introduce jank if not implemented properly.

The core benefit of using pure CSS not only offloads all the extra drawing in the DOM, but also allows for hardware acceleration and a silky smooth effect that won’t spike your CPU.

How to implement a minimal parallax effect

First let’s define our HTML markup.

<div class="MainContainer">

  <div class="ParallaxContainer">
    // Headlines for the page

  <div class="ContentContainer">
    <div class="Content">
      // Put the rest of my page content here

and here’s some basic CSS to get it started:

.MainContainer {
  perspective: 1px;
  transform-style: preserve-3d;
  height: 100vh;
  overflow-x: hidden;
  overflow-y: scroll;

.ParallaxContainer {
  display: flex;
  flex: 1 0 auto;
  position: relative;
  height: 100vh;
  transform: translateZ(-1px) scale(2);
  z-index: -1;

.ContentContainer {
  display: block;
  position: relative;
  background-color: white;
  z-index: 1;

The magic is in the perspective, and transform rules. We define our MainContainer with perspective. This sets the stage for our transform rules. In our ParalaxContainer, we transform it to basically push that div into the background using translateZ(-1px). The items and text in this container will look half the size that they should be since we’ve pushed them into the background. To compensate for this, we add scale. It will resize the background content back up to its original size, yet the scroll effect is as if it was still in the background.

What’s cool about this, is that you have the ability to play with the depth. You can change how far into the background you’d like to push it by changing the translateZ and scale rules. What this does is allows you to change how fast or slow your background will scroll out of view.

For example, try this for a more subtle effect:

transform: translateZ(-5px) scale(6);

Check out this demo, and try playing with the values in the CSS.
