Simple Pure CSS Parallax Scrolling Effect Tutorial | thecodingpie

Let's build a simple yet beautiful parallax scrolling effect using pure CSS only?

thecodingpie . . 7 min read . 484 Hits

Howdy Folks, Welcome to this another wonderful tutorial on creating a simple yet beautiful parallax scrolling effect using pure CSS only. No Javascript libraries used ;)

Before jumping right in, first, take a look at the finished product at Codepen--> https://codepen.io/thecodingpie/pen/JjGJMMB

You can get the full source code at the end. Or you can just download the completed project from GitHub --> https://github.com/the-coding-pie/Parallax-Effect

Note: The parallax effect does not always work on mobile devices. So if you are using a mobile device to see the finished demo, then some of you may encounter some difficulties seeing the demo at its full glory.

Parallax Scrolling Effect

Parallax scrolling effect is an illusion where the background content (eg: an image) is moved at a different speed than the foreground content while scrolling. 

That's the theory part. We are going to achieve this effect using only a few CSS styles namely perspective, transform-style, transform, and z-index. If you wonder what they are, don't worry at all you will understand everything by the end of this tutorial. Trust me it's so simple :)

Let's Build it :)

This is my file structure:

file structure

 

  • First, create a folder named "Parallax Effect". This is our root folder that holds everything. Then open it inside any text editor you like. Here I am going to use visual studio code.
  • Then create an "index.html" file.
  • Then create two folders:
    • One named "css" --> Inside this folder create a file named "styles.css"
    • Then another folder named "img" --> This holds our image. You can grab the image I used from here. After downloading it, rename the image to "bg" then put it inside "img" folder you created.

That's it. Now you should have a folder structure similar to above. Now the HTML part...

HTML

This is the structure of our "index.html" file:

parallax html structure layout graph

And this is the code. Copy/Type this inside "index.html":

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="css/styles.css">
  <title>Parallax</title>
</head>
<body>

  <header>
    <h1>Life Is Beautiful :)</h1>
  </header>
  <section class="paragraph">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Quas omnis accusamus unde deserunt. Sapiente laboriosam sequi cupiditate sint debitis veritatis exercitationem dignissimos est enim molestias accusamus, suscipit nostrum asperiores minus!
    Eligendi ab fugiat dignissimos ipsam minima necessitatibus provident repellendus neque odit numquam aliquam expedita suscipit doloribus nesciunt facilis, molestiae quibusdam! Odit excepturi ab iure, aspernatur nemo aut repudiandae? Doloribus, earum?
    Eius blanditiis maxime impedit harum quasi pariatur atque beatae omnis expedita dolorum, vero explicabo numquam mollitia libero ut ratione, sit, amet assumenda voluptatem deserunt magnam rem facilis. Dolor, porro non?
    Tempore atque fugit quaerat neque esse? Unde doloremque odit distinctio mollitia quae quasi itaque atque dolor voluptatibus eligendi nemo labore repudiandae, sit maiores at eius. Nulla ipsa voluptatibus laboriosam culpa!
    Iusto ipsum aliquam obcaecati a ullam fuga dolorem dolores, eius, beatae corporis repudiandae quibusdam ab natus? Voluptates unde quaerat quas, placeat, blanditiis hic totam harum tempore assumenda ullam voluptatibus quod.
  </section>

</body>
</html>

Inside the <body>, we have a <header> and a <section class="paragraph">. Inisde <header>, there is an <h1> element. And inside <section class="paragraph">, we have some dummy "lorem ipsum" text. 

Open it with "Live Server" and take a look at it in the browser.

Now comes the most important part, the CSS part... 

CSS

Open the "styles.css" file and type the following step by step. Here I am going to follow the style like code first then explain it then again give code then explain it and so on and so forth:

* {
  padding: 0;
  margin: 0;
}

The above code removes the default padding and margin given by the browser.

/* this style for "html" is must, otherwise nothing will work */

html {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

This code is a must. Otherwise, nothing will work. Here we are grabbing the html element and set its width: 100% and height: 100% and overflow: hidden.

body {
  width: 100%;
  height: 100%;
  perspective: 1px;
  transform-style: preserve-3d;
  overflow-x: hidden;
  overflow-y: scroll;
  font-family: sans-serif;
  color: #fff;
}

Now we are targeting the body element and set its height: 100% and width: 100%

Then we are setting the perspective: 1px. The perspective property is used to give a 3D-positioned element some perspective. This property gives us the 3D depth we want. This defines how far the object is away from the user. So a lower value will result in a more intensive 3D effect. One more important thing is that when giving this property to an element, it is the Child elements that get the perspective view, not the element itself.

Then the transform-style: preserve-3d. The transform-style property sets whether children of an element are positioned in the 3D space or are flattened in the plane of the element. This property allows the element to sit inside the 3D space we created. This property is not inherited, so it must be set manually for the child elements.

Then we are setting overflow-x: hidden and overflow-y: scroll and some other basic settings.

header {
  width: 100vw;
  min-height: 100vh;
  position: relative;
  transform-style: preserve-3d;
}

Here, we are selecting the header element and setting its width and height to 100vw and 100vh. "vw" stands for view-width and "vh" stands for view-height. It is the width and height of the device screen.

Then we are setting position: relative. Because we are going to absolutely position everything in relative to our header element. If you want to learn more about positioning, here is a short video by Red Stapler --> https://www.youtube.com/watch?v=3PDQDRJq5Ls

As I told earlier, we need to manually set transform-style: preserve-3d to all the children we want. That's what we are doing in the last line.

header h1 {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

To position the h1 in the exact middle of the header tag, we set position: absolute, then push it from top: 50% and left: 50%. Then give transform: translate(-50%, -50%).

/* placing the actual background image using pseudo selector */
header::before {
  content: "";
  min-height: 100vh;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  background-image: url(../img/bg.jpg);
  background-size: cover;
  transform: translateZ(-1px) scale(2);
  z-index: -1;
}

Now here is where we set our background image. We use the ::before pseudo-selector to do this. First we set content: "", then set min-height: 100vh, then set position: absolute and set top: 0, left: 0, right: 0. This positions the image top-left. 

Now give the image through the background-image property. Then set the background-size to cover.

Then push the image along the z-axis -1px through transform: translateZ(-1px). When we do so, the image will be pushed away from the user. So its size will decrease. So we need to scale it up. That's what we are doing on the second-last line. The scale value will depend on the values of perspective and the translateZ. Finally, set the z-index: -1, so that the background image will be less important than the forward content.

.paragraph {
  position: absolute;
  top: 100vh;
  background-color: #111;
  line-height: 2;
  padding: 70px;
  font-size: 1.2rem;
}

This final piece of code is for styling our <section class="paragraph"> and the content inside it. This is pretty self-explanatory and this is also less important too. 

That's it! Now if you take a look at the finished web page in the web browser, you can see the parallax effect at its full glory :)

Here is the final code:

The code for "index.html":

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="css/styles.css">
  <title>Parallax</title>
</head>
<body>

  <header>
    <h1>Life Is Beautiful :)</h1>
  </header>
  <section class="paragraph">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Quas omnis accusamus unde deserunt. Sapiente laboriosam sequi cupiditate sint debitis veritatis exercitationem dignissimos est enim molestias accusamus, suscipit nostrum asperiores minus!
    Eligendi ab fugiat dignissimos ipsam minima necessitatibus provident repellendus neque odit numquam aliquam expedita suscipit doloribus nesciunt facilis, molestiae quibusdam! Odit excepturi ab iure, aspernatur nemo aut repudiandae? Doloribus, earum?
    Eius blanditiis maxime impedit harum quasi pariatur atque beatae omnis expedita dolorum, vero explicabo numquam mollitia libero ut ratione, sit, amet assumenda voluptatem deserunt magnam rem facilis. Dolor, porro non?
    Tempore atque fugit quaerat neque esse? Unde doloremque odit distinctio mollitia quae quasi itaque atque dolor voluptatibus eligendi nemo labore repudiandae, sit maiores at eius. Nulla ipsa voluptatibus laboriosam culpa!
    Iusto ipsum aliquam obcaecati a ullam fuga dolorem dolores, eius, beatae corporis repudiandae quibusdam ab natus? Voluptates unde quaerat quas, placeat, blanditiis hic totam harum tempore assumenda ullam voluptatibus quod.
  </section>

</body>
</html>

Code for "styles.css":

* {
  padding: 0;
  margin: 0;
}

/* this style for "html" is must, otherwise nothing will work */

html {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

body {
  width: 100%;
  height: 100%;
  perspective: 1px;
  transform-style: preserve-3d;
  overflow-x: hidden;
  overflow-y: scroll;
  font-family: sans-serif;
  color: #fff;
}

header {
  width: 100vw;
  min-height: 100vh;
  position: relative;
  transform-style: preserve-3d;
}

header h1 {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* placing the actual background image using pseudo selector */
header::before {
  content: "";
  min-height: 100vh;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  background-image: url(../img/bg.jpg);
  background-size: cover;
  transform: translateZ(-1px) scale(2);
  z-index: -1;
}

.paragraph {
  position: absolute;
  top: 100vh;
  background-color: #111;
  line-height: 2;
  padding: 70px;
  font-size: 1.2rem;
}

Conclusion

I hope you enjoyed this tutorial. If you had any doubts, then please comment them below. Thank you ;)

About Me

Hey folks, my name is Aravind, and I am the man behind this website. To know more about me, check out the About Me page. If you like and enjoy my content, then please consider supporting what I do through - Buy Me a coffee.

Comments(2)
Bounty Hunter on Sep 28, 2020
Hello, https://bherbert7.github.io/bounty.html I have tried to merge the parallel effect along with the donut pages indoor tutorials (which are awesome, btw!). However, if you take a look at my site, I have encountered a few issues with the merge: 1. I would like the header image to be about 50-70% of what it is now. More so the height of the donuts example, instead of it being full page to start with. 2. My section two begins to scroll behind the image way too soon, cutting off the top part before you can see the full section. Do I have to move everything down to counter this? But then how will that affect different screen sizes? 3. When I made just the donuts shop, my nav bar buttons stayed on top of everything. With the merger, the nav buttons get stuck behind the polaroids in section 4? I tried z-index, but I couldn't get it to stay in front for that (or all) section. Your help is greatly appreciated! Thank you.
thecodingpie on Sep 28, 2020
Hey @Bounty Hunter, I checked your site. Btw it looks great! I have seen a few mistakes: 1). If you want your image to be 50-70% height then why are giving it a min-height: 100vh; ? 2). Solution to 2nd problem is that give a margin-top: 29rem; to .second-div. 3). For problem 3, I think you have to go through my tutorial once more but carefully. 4). Give z-index: -10 to the image and buttons not for the confetti. If you are still stuck please comment them or mail me (check your mail box for the mail you had given)
Leave Your Comments

Similar Posts

9 Best Web Development Courses Online for 2020

. 13 min read . 2.2K hits

How to create a responsive landing page in HTML5 and CSS3 - thecodingpie

. 17 min read . 433 hits