š„ What weāll be building
Firstly, letās look at a relatively simple parallax effect. We can see this on our own website https://daily-fire.com. Notice the graphics in the background move slightly slower than the content in the foreground. The effect is subtle but is a great way to add give a webpage depth.
Parallax on https://daily-fire.com
The next implementation is applying the parallax effect to an element on a page, rather than the whole page itself. This is typically where people might turn to a JS implementation, but we will be covering how to achieve this with CSS. The website https://www.whispir.com uses a CSS parallax effect to add to the illusion of depth on their illustrations:
Parallax on https://whispir.com
Here the illustrations are brought to life by having the floating elements move at different speeds as you scroll. This creates a really nice depth effect, complimenting the illustration nicely.
š„ Understanding the approach
Both of the examples we will be implementing today use the same technique but vary slightly in implementation.
This approach relies on the CSS3 transform
and perspective
properties. Conceptually, we will be creating a 3D space in which we place different layers at different points on the z-axis.
If the notion of a Z axis is unfamiliar to you, you can think of it like this:
X axis is left and right
Y axis is up and down
Z axis is forward and backward
Before getting started on the parallax letās understand this 3D space visually. Weāll start with some code:
Which gives us:
Pretty exciting stuff! š
Whatās important about this is the use of the perspective
property on line 9. You can think of that as assigning 8px of ādepthā to the container. Letās take a look at what happens when we start to play with the position of the .element
along the Z axis.
There we go! By animating the position along the Z axis it appears that the box is getting bigger. If you donāt quite get what is happening here, the following GIF includes some guides to help you see how it is moving, as if it were in a cube:
This is the basis for how our CSS parallax will work. We place the different layers at different positions along the z-axis
š„ Implementing parallax
With the knowledge of the previous example we can move onto more practical applications of the perspective
property.
First letās setup our parallax container which will wrap our ālayersā
Here we set a few additional properties that ensure that the scrolling happens within our .parallax-container
element. If the scroll happens within the container we can rely on CSS to handle the āparallaxingā.
Letās see the markup:
And the styles:
This results in:
Getting somewhere now!
However, upon closer inspection something isnāt quite right. Our text is a lot bigger than it should be. This is because we are translating the .foreground
towards us 3px
, and just like in real life, if you bring an object closer to your eyes, it gets bigger!
To counteract this we need to apply a scale
to the layer to make it render at the correct size. The Google article gives us a handy formula to determine what the scale
value should be. The formula is:
(perspective ā distance) / perspective = scaleFactor
For our example, our perspective
is 8px
and we have moved our layer a distance
of 3px
. Letās plug that into the formula and see what we get:
(8 ā 3) / 8 = 0.625
Finally, letās apply this as a scale:
That looks better! You can confirm that you have done it correctly by setting transform: translateZ(0) scale(1);
on the .foreground
and seeing no difference in size (you can do this in the Codepen below).
Bonus: if you are using Sass or a similar CSS preprocessor we can create a function to calculate this for us. Here it is in SCSS:
With just that little bit of CSS we have created a parallax effect! Here is the result:
Check it out on Codepen too:
š„ Expanding
Letās expand on this example a little and apply a parallax effect to an image on the page, rather than the whole background of the page.
First, take a look at the markup we will be using:
And the styles:
Note: Here we are using SCSS and the helper function we described above to calculate the scale factor of our layer
Now when we scroll we can see that the different layers move at different speeds!
Layers further along the Z axis (greater translateZ
value) will appear to move faster.
Have a play with code and try tweaking the variables to see how the effect changes!
And thatās it! We have just implemented performant, multi-layer parallax with around 20 lines of CSS šŖ
š„ Gotchaās
This effect does have one slight quirk on iOS Safari. This effect seems to disable inertia scrolling (that nice scroll effect youāre used to on your phone, where the screen keeps scrolling after you āflickā). Luckily there is an easy fix, simply add this CSS property to your parallax container:
This should fix the scrolling issue on iOS Safari!
The Performant Parallaxing article goes into more depth on this topic.
š„ Wrapping Up
I hope to have shown that this effect can be really cool. Paired with the fact that itās super easy to implement, Iām hoping you are tempted to go ahead and use this in your own projects.