DEV Community

loading...

Let's make a CSS cube

joeattardi profile image Joe Attardi ・3 min read

You can do a lot with CSS transforms! In this post we'll walk through making a 3D cube.

First, let's create the markup:

<div class="container">
  <div class="cube">
    <div class="face top">Top</div>
    <div class="face bottom">Bottom</div>
    <div class="face left">Left</div>
    <div class="face right">Right</div>
    <div class="face front">Front</div>
    <div class="face back">Back</div>
  </div>
</div>

Each face of the cube is its own div element. Let's create some initial styles:

.container {
  width: 200px;
  height: 200px;
  perspective: 500px;
  margin: 100px;
}

.cube {
  position: relative;
  width: 200px;
  height: 200px;
  transform-style: preserve-3d;
}

.face {
  width: 200px;
  height: 200px;
  background: skyblue;
  border: 2px solid black;
  position: absolute;
  opacity: 0.5;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: Arial, sans-serif;
  font-size: 2rem;
}

We've given some styling to the cube faces and absolutely positioned them so they are all sitting on top of one another. First, we will rotate each face so that it's facing the proper direction. The next step will be to move each face out from the center to the edges of the cube.

Here is what we have so far:

The initial positioned elements

We are currently looking at the cube head-on. It will be easier to visualize if we rotate our "camera" a bit. Let's add a rotate3d transform to the cube:

.cube {
  position: relative;
  width: 200px;
  height: 200px;
  transform-style: preserve-3d;
  transform: rotate3d(1, 1, 0, 45deg);
}

Now the elements are rotated at an angle, so we can see the 3D structure better:

Rotated in 3D space

Let's tackle the front first. Our cube is 200px by 200px by 200px. Currently all the elements are in the dead center of the cube. The front is already facing the right direction, we just need to move it out by 100px so that it is at the front edge. Let's add a new rule for the front and move it out:

.front {
  transform: translateZ(100px);
}

Now the front face of the cube is in place:

The front face in position

Next is the back. It is already in the proper plane, but we need to rotate it 180 degrees around the y-axis so that the text is facing outwards. Like the front, we also need to move it out by 100px:

.back {
  transform: translateZ(-100px) rotateY(180deg);
}

The back face is now in the proper position:

Back face in position

Let's do the left and right next. These need to be rotated 90 degrees around the y-axis so that they are both facing outwards on each side. The left side needs to be rotated by -90 degrees.

Then they need to be moved along the x-axis to the edges of the cube:

.left {
  transform: translateX(-100px) rotateY(-90deg);
}

.right {
  transform: translateX(100px) rotateY(90deg);
}

Left and right in position

Lastly, we need to position the top and bottom. These need to be rotated 90 degrees around the x-axis so that they are facing up and down. Again, the top will need a rotation of 90 degrees and the bottom -90 degrees, so that the text direction is correct.

.top {
  transform: translateY(-100px) rotateX(90deg);
}

.bottom {
  transform: translateY(100px) rotateX(-90deg);
}

The completed cube

Looks like a cube!

To show off our new cube, let's give it a turning animation:

@keyframes turn {
  from { transform: rotate3d(0, 0, 0, 0); }
  to { transform: rotate3d(1, 1, 0, 360deg); }
}

.cube {
  position: relative;
  width: 200px;
  height: 200px;
  transform-style: preserve-3d;
  animation: turn 5s linear infinite;
}

Lastly, we want to be mindful of accessibility. If the user has disabled animations in their operating system, let's not animate the cube but rather display it at the 45 degree angle we had before:

@media (prefers-reduced-motion: reduce) {
  .cube {
    animation: none;
    transform: rotate3d(1, 1, 0, 45deg);
  }
}

Here is the finished product in a CodePen:

Did you like this post? Learn more CSS in my upcoming book, Modern CSS!

Discussion (1)

pic
Editor guide
Collapse
bitdweller profile image
Pedro Pimenta

Yeah! This is something I have never done. Always looked like something super-hard but it seems to be attainable for me :)

Thanks for the intro!