Draw and Animate a Diamond Using CSS Only

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 the overflow: visible property.

.wrap { position:absolute; width:0px; height:0px; top:50%; left:50%; transform-origin:0 0; transform-style: preserve-3d; overflow:visible; }

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); } }

Triangles

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 { position:absolute; left:-100px; top:-50px; 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