I recently saw something very interesting on algoExpert. IO /.
At the beginning, I thought I needed to use what JS library to achieve, opened the console research, the original CSS can be achieved, well, I am ignorant, ha ha. So write a blog about it.
Six surface
First, make 6 faces in HTML.
<div class="cube-container">
<div class="cube-faces">
<div class="cube-face cube-face-front">
<img src="https://yanhaixiang.com/cube/images/js.png" alt="js">
</div>
<div class="cube-face cube-face-back">
<img src="https://yanhaixiang.com/cube/images/python.png" alt="python">
</div>
<div class="cube-face cube-face-top">
</div>
<div class="cube-face cube-face-bottom">
</div>
<div class="cube-face cube-face-left">
<img src="https://yanhaixiang.com/cube/images/golang.png" alt="golang">
</div>
<div class="cube-face cube-face-right">
<img src="https://yanhaixiang.com/cube/images/cpp.png" alt="cpp">
</div>
</div>
</div>
Copy the code
Container is a cube, cube-faces is a six-sided container, and the remaining div is a six-sided container with an IMG inside.
The effect is a row:
Set six faces
The second step is to stack the six surfaces together. Simply. Cubo-faces sets position: relative and. Cubo-face sets position: Absolute to make all six sides separate from the document flow and overlap.
.cube-faces {
position: relative;
width: 300px;
}
.cube-face {
position: absolute;
height: 300px;
width: 300px;
outline: 1px solid #02203c;
box-shadow: inset 0 0 100px #02203c;
background-color: #3e526a;
opacity: 0.75;
}
.cube-face img {
width: 100%;
height: 100%;
}
Copy the code
Rotary surface
Rotate the six faces into a cube using transform: Rotate.
.cube-face.cube-face-front {
transform: translateZ(150px);
}
.cube-face.cube-face-back {
transform: translateZ(-150px) rotateY(180deg);
}
.cube-face.cube-face-top {
transform: rotateX(-90deg) translateY(-150px);
transform-origin: top center;
}
.cube-face.cube-face-bottom {
transform: rotateX(90deg) translateY(150px);
transform-origin: bottom center;
}
.cube-face.cube-face-left {
transform: rotateY(270deg) translateX(-150px);
transform-origin: left center;
}
.cube-face.cube-face-right {
transform: rotateY(-270deg) translateX(150px);
transform-origin: top right;
}
Copy the code
Unfortunately, the effect is still a “flat”.
First of all, these six faces are actually transformed into cubes, but because we’re only looking at one face, it still looks two-dimensional. If it had been a cube, we would have been looking at the JS side instead of the Python side. Isn’t Python rotated backwards?
Although Python is used as the back, in HTML, the Python div comes after the JS div, so Python takes precedence.
To remove the ordering effect of HTML, you can add to.cube-faces:
.cube-faces {
position: relative;
width: 300px;
transform-style: preserve-3d; /* 3D */
}
Copy the code
Now the JS side of the cube is coming towards us:
Stand up
Let’s take a closer look at the PERSPECTIVE property of CSS, which can be interpreted as where our eyes are. As I said, the reason we see two-dimensional surfaces is because our eyes are fixed on one surface, so all we have to do is lift our eyes up and look down on the whole cube, and the cube becomes “solid”.
/* Put the cube in the center */
body {
display: flex;
align-items: center;
justify-content: center;
}
.cube-container {
margin-top: 200px;
perspective: 800px; /* Look at the extension */
perspective-origin: 50% 100px; /* Center your eyes horizontally and lift 100px */
}
Copy the code
It’s starting to smell.
Turn up
Next, to make the cube a little more dynamic, define a @KeyFrames animation:
@keyframes spin { /* Y-axis rotation */
0% {
transform: rotateY(0);
}
100% {
transform: rotateY(360deg); }}.cube-faces {
position: relative;
width: 300px;
transform-style: preserve-3d;
animation: spin 10s infinite linear; / * * / animation
}
Copy the code
Add some shadow
Now the cube is solid, but it always feels fake because of the lack of shadows. We’ll add a small shadow to the bottom div:
.cube-face.cube-face-bottom {
transform: rotateX(90deg) translateY(150px);
transform-origin: bottom center;
box-shadow: 0 0 100px # 000; / * * / shadow
}
Copy the code
And you’re done!