Draw and Animate a Diamond Using CSS Only

last updated on 2018-12-14

The animation below was created without any JavaScript and only using HTML elements and CSS properties.

The Container

First let's create a container CSS class that will contain the diamond elements. Because we're going to be rotating the elements in a 3D space, we define the center of rotation in the middle/center of the area. The idea here is to center the element vertically and horizontally while maintaining objects visible using theoverflow: visible property.

.wrap {
  transform-origin:0 0;
  transform-style: preserve-3d;

Next we create the HTML container element, or better say the containers.

Notice how we need one container for each axis of rotation. This demo actually only uses X and Y axis but for the sake of 3D joy, we also add support for rotation around the Z axis.

Next, we use CSS to set and/or animate these axes of rotation.

.rotor-x {
  transform: rotateX(-22deg);
.rotor-y {
  animation: spinY 12s infinite linear;
@keyframes spinX {
  from { transform: rotateX(0); }
  to { transform: rotateX(360deg); }
@keyframes spinY {
  from { transform: rotateY(0); }
  to { transform: rotateY(360deg); }


Now let's create a .triangle class that will be applied to every single face of the diamond. These faces are also referred here as triangles.

.triangle {
  width: 0;
  height: 0;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;
  border-bottom: 100px solid #33AFFF; 
  animation: lighting 12s infinite linear;

Once our class is ready we add the triangles to our containers as below:

And now the most tedious part, we need to position each triangle in a 3D space to create a diamond:

/** Bottom Down **/
.triangle.bottom {   
  transform-origin: 50% 0%; }
.triangle.bottom.face-1 {
  transform: translateY(90px) rotateY(0deg) rotateX(35deg)  scaleX(.24) scaleY(-1) ;  }
.triangle.bottom.face-2 {
  transform:  translateY(90px) rotateY(45deg) rotateX(35deg)  scaleX(.24) scaleY(-1) ; }
.triangle.bottom.face-3 { 
  transform:  translateY(90px) rotateY(90deg) rotateX(35deg)  scaleX(.24) scaleY(-1) ; }
.triangle.bottom.face-4 { 
  transform:  translateY(90px) rotateY(135deg) rotateX(35deg)  scaleX(.24) scaleY(-1) ; }
.triangle.bottom.face-5 { 
  transform:  translateY(90px) rotateY(180deg) rotateX(35deg)  scaleX(.24) scaleY(-1) ; }

etc ...

And so on...

Taking it further

Because we're actually not using any lighting system or normals, we add a cheap trick to simulate reflection by adding random blinking animations to the tiangles, and apply different delays to prevent duplicates.

/* Create blinking animation loops */
@keyframes lighting {
  0% {   border-bottom-color:#33AFFF; }
  50% {  border-bottom-color:#BBE8FF; }
  100% { border-bottom-color:#33AFFF; }
@keyframes lighting-lighter {
  0% {   border-bottom-color:#72C8FF; }
  50% {  border-bottom-color:#99EAFF; }
  100% { border-bottom-color:#72C8FF; }
/* Apply them to the triangle with various delay values */
.triangle.up {   
  animation: lighting-lighter 12s infinite linear; 
.triangle.up.face-1 { 
  animation-delay: -3500ms;
.triangle.up.face-2 { 
  animation-delay: -4500ms;
etc ...

Source Code

Checkout the full source here

Join The Conversation