Subscribe

Creating a 3D dice in CSS

āœļø

A first look at 3D CSS - a dice

27 Jul, 2022 Ā· 7 min read

Iā€™m finally going to touch on a subject Iā€™ve been putting off for way too long in this article.

3D in CSS!

Yes, 3D, and what better example of trying and making a 3D dice in CSS.

The result of this article will be this rotating dice. (Code and demo at the bottom)

Setting up the HTML

Letā€™s start with the HTML. We need a dice container and six sides to it.

<div class="dice">
  <div class="side one"></div>
  <div class="side two"></div>
  <div class="side three"></div>
  <div class="side four"></div>
  <div class="side five"></div>
  <div class="side six"></div>
</div>

That will be all for our HTML part. Letā€™s quickly move on to the fun part, which will be the CSS.

Basic styling

Letā€™s start with some basic styling.

First, I ensured the dice element was in the middle of the page since itā€™s easier to work with.

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

Then I moved on to arranging the dice to be a big square box.

.dice {
  position: relative;
  width: 200px;
  height: 200px;
}

Then each side is another wrapper that centers all its children (the dots).

.side {
  width: 100%;
  height: 100%;
  background: #da0060;
  border: 2px solid black;
  position: absolute;
  opacity: 0.7;
  display: flex;
  align-items: center;
  justify-content: center;
}

By now, you should see something that looks like this:

Dice wireframe setup

It might not look like much, but trust me, there are six sides!

Creating dice dots in CSS

I will start by explaining how I achieved the dots since this is quite an excellent technique.

I didnā€™t want to use a lot of extra divs, so each option only consists of one pseudo selector.

And it starts with the #1 side.

.side {
  &:before {
    content: '';
    width: 20%;
    height: 20%;
    background: black;
    border-radius: 50%;
  }
}

One dot on the dice in CSS

I can hear you think, but what about the others?

And there is a very cool trick for that! We can leverage the box-shadow rule for it.

And if we think about it, there are only seven positions a dot can have. We already have one, so letā€™s look at the other six.

&:before {
  content: '';
  width: 20%;
  height: 20%;
  background: black;
  border-radius: 50%;
  box-shadow: red -50px -50px 0px 0px, blue -50px 0px 0px 0px,
    yellow -50px 50px 0px 0px, green 50px -50px 0px 0px, orange 50px 0px 0px 0px,
    white 50px 50px 0px 0px;
}

I used random colors in the example above so you can see which position is which dot.

All possible dots in CSS

Note: The black dot is our initial dot.

Now letā€™s go ahead and create all possible dot variants.

For the #2 side, we donā€™t need the initial dot so that we can turn off the background.

.two {
  &:before {
    background: transparent;
    box-shadow: #000 -50px -50px 0px 0px, #000 50px 50px 0px 0px;
  }
}

For number three we can use a similar approach, but not hide the background:

.three {
  &:before {
    box-shadow: #000 -50px 50px 0px 0px, #000 50px -50px 0px 0px;
  }
}

Then for the fourth one:

.four {
  &:before {
    background: transparent;
    box-shadow: #000 -50px 50px 0px 0px, #000 -50px -50px 0px 0px,
      #000 50px 50px 0px 0px, #000 50px -50px 0px 0px;
  }
}

And on to number five:

.five {
  &:before {
    box-shadow: #000 -50px -50px 0px 0px, #000 -50px 50px 0px 0px,
      #000 50px -50px 0px 0px, #000 50px 50px 0px 0px;
  }
}

And last but not least, number six, which we used as our template.

.six {
  &:before {
    background: transparent;
    box-shadow: #000 -50px -50px 0px 0px, #000 -50px 0px 0px 0px,
      #000 -50px 50px 0px 0px, #000 50px -50px 0px 0px, #000 50px 0px 0px 0px, #000
        50px 50px 0px 0px;
  }
}

Our result will look weird since our transparent layers sit on each other.

Dice dots in CSS

Arranging a dice in 3D CSS

Now that we have all our elements in place letā€™s start the fun and apply our 3D effect!

We can achieve a 3D perspective in CSS by using transforms. We have three axes to play with: the X, Y, and Z axes.

First, letā€™s put our cube in perspective.

.dice {
  transform-style: preserve-3d;
  transform: rotateY(185deg) rotateX(150deg) rotateZ(315deg);
}

Now, it might look a bit weird if we look at what we got.

3D effect in CSS

This is already 3D, but it doesnā€™t look like a cube yet. We need to modify each side to do its transformation.

Letā€™s start with side one.

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

This will lift the side, so it sticks out at the top.

3D CSS cube lifting one side

You might already be able to see where this is going. Now letā€™s do the opposite end, which is side number six.

We will offset that to a negative 100px. This means the distance between one and six is now 200px (our cube size).

.six {
  transform: translateZ(-100px);
}

CSS Dice two sides offset

Now letā€™s do the number two side. This one needs to be connected by transforming a different axis.

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

Side number two CSS dice

Now the easiest one to connect is the opposite, side number five.

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

As you can see, itā€™s the same transformation, but we offset it by 200 pixels.

Side number 5 CSS dice

Two more sides left. Letā€™s do number three.

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

As you can see, itā€™s the opposite transformation from two to five.

Side number three

The last one we need is number four, which will be the opposite of number three.

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

With this one in place, our dice are complete!

3D Dice made in CSS

Animating the dice

Now that we have our dice letā€™s make it a bit more interactive by animating it!

Each of the sides we described can also be animated, Iā€™ll only be turning the dice on one side, but you can have a play around with any of them to achieve a different animation.

@keyframes rotate {
  from {
    transform: rotateY(0) rotateX(45deg) rotateZ(45deg);
  }
  to {
    transform: rotateY(360deg) rotateX(45deg) rotateZ(45deg);
  }
}

.dice {
  animation: rotate 5s linear infinite;
}

You can find the completed example in this CodePen.

See the Pen Untitled by Chris Bongers (@rebelchris) on CodePen.

Thank you for reading, and letā€™s connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Spread the knowledge with fellow developers on Twitter
Tweet this tip
Powered by Webmentions - Learn more

Read next šŸ“–

Modifying an SVG path with CSS

10 Dec, 2022 Ā· 2 min read

Modifying an SVG path with CSS

Animate an SVG path with CSS

9 Dec, 2022 Ā· 2 min read

Animate an SVG path with CSS

Join 2097 devs and subscribe to my newsletter