paint-brush
How to Create a 3D Effect With CSS Perspective and Book Animationby@hacker4337770
274 reads

How to Create a 3D Effect With CSS Perspective and Book Animation

by JShaApril 5th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

If you didn’t fully understand how to make 3d in the way you want using plain CSS, I hope this mini article can be of help. When we set `perspective` for the element, it tells the browser that a child of this element should behave as though they are in 3D space.
featured image - How to Create a 3D Effect With CSS Perspective and Book Animation
JSha HackerNoon profile picture

If you read about 3d in CSS and didn’t fully understand how to make 3d in the way you want using plain CSS, I hope this mini article can be of help. In the end, you will be able to build something like this :)

Perspective

What is perspective in CSS? When we set perspective for the element, it tells the browser that a child of this element should behave as though they are in 3D space.


Amount of perspective determines the distance between user and z=0 plane.


I tried to figure out how it can be that the more perspective amount we set, the less perspective we see. It was really confusing for me at first. Unless I draw some schema:

Imaginary perspective

When we change the z coordinate (translateZ()) for the child, we move the child along this imaginary z-axis toward the user. So the further this z=0 plane is from us, the less noticeable the change is.

Perspective-origin

perspective-origin: horisontal-position vertical-position determines the position of the user’s eyes relative to the transformed elements. By default, this position is centered: perspective-origin: 50% 50%

Transform-style

transform-style: preserve-3d allows children of the element to be positioned in 3D space. And my question was: but isn’t it what perspective for? Actually, no. Transform-style doesn’t add depth. If there is no perspective in the parent’s element, then we won’t see actual 3d- representation:

transform-style: preserve-3d just allows children to live in their own 3D space.

Book Animation

Now, let’s do some cool animation 😃.


First of all, our index.html body will look like this:

  <div class="container">
    <div class="book">
      <span class="shadow"></span>
      <div class="back"></div>
      <div class="cover-end"></div>
      <div class="page last">
        <button class="btn-tale">Tale begins...</button>
      </div>
      <div class="page third"></div>
      <div class="page second"></div>
      <div class="page first"></div>
      <div class="cover">
        <img src="https://cdn.pixabay.com/photo/2024/03/30/12/44/landscape-8664708_1280.png" alt="">
      </div>
    </div>
  </div>


In what follows, I omit insignificant properties for the topic; you can look at them in the original code in the introduction.


We have a div block for every page since every page will behave differently. Let’s first add perspective to the container block:

.container {
  perspective: 500px;
  perspective-origin: 50% 50%;
}

We use default perspective-origin. But I preferred to explicitly set it for better understanding. So, our eyes are at the center of the container and z=0 plane is at 500px distance from us.


At this point, our book block is set on the plane z=0 and doesn’t have any 3d features. Let’s add transform-style to allow pages to behave in their own 3d-space:

.book {
  position: relative;
  transform-style: preserve-3d;
}

.book>div {
  position: absolute;
  top: 0;
  left:0;
  transition: transform 2s;
}


Now, let’s add actual 3d :)

.cover {
  transform: scaleY(1.05) rotateY(-10deg);
}

.page.first {
  transform: translateX(2px) rotateY(-10deg);
}

.page.second {
  transform: translateX(4px) rotateY(-10deg);
}

.page.third {
  transform: translateX(6px) rotateY(-10deg);
}

.page.last {
  transform: translateX(8px) rotateY(-10deg);
}


To achieve volume, we move every page a little to the right and rotate it around the y-axis. Now, let’s change the behavior of the book when we hover over it:

.book:hover .cover{
  transform: rotateY(-150deg);
}

.book:hover .page.first{
  transform: translateX(2px) rotateY(-150deg);
}

.book:hover .page.second{
  transform: translateX(4px) rotateY(-130deg);
}

.book:hover .page.third{
  transform: translateX(6px) rotateY(-110deg);
}

Alright, here, we change rotation from -10deg to more extreme values to achieve the “opening effect.” Also, we should save our translateX, since transform rewrites all its’ previous values.


And… that’s it! I hope you understand now a little more about perspective in CSS 🙂.