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">
      &nbsp;
    </div>
    <div class="cube-face cube-face-bottom">
      &nbsp;
    </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!