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

Written by hacker4337770 | Published 2024/04/05
Tech Story Tags: css-animation | animation | 3d | 3d-effect-guide | how-to-make-a-3d-effect | css-perspective-tutorial | perspective-in-css-explained | book-animation-guide

TLDRIf 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.via the TL;DR App

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 :)

https://codepen.io/juliashlykova/pen/XWQzXVm?embedable=true

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:

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:

https://codepen.io/juliashlykova/pen/BaEmWqq?editors=1100&embedable=true

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 🙂.


Written by hacker4337770 | Passionate for web development
Published by HackerNoon on 2024/04/05