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:
Table of contents
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 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 from us the less noticeable the change is.
Perspective-origin
perspective-origin: horizontal-position vertical-position
determines the position of 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 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 parent’s element then we won’t see actual 3d-representation:
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 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 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 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 “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.
Top comments (0)