
Create the illusion of a spinning 3D object with CSS
One of the aims of 3D is to create the illusion of a solid object. But there are three problems. The first is working out the geometry of your scene. You literally have to calculate the position of every element.
The other problem is setting up your scene so it’s easy to animate. Making the right choices about parent and child relationships can make all the difference here. And don’t forget you need to include a container to manage perspective.
The final problem is that there are assorted subtle CSS gotchas that affect perspective in unobvious ways. They are annoying, so we’ve tried to discuss them all.
Sketch a cube
Cubes have six faces, so we’ll use six elements. We’ll create a div for each face, and put them inside a single container div with the id of ‘cube’.
001 <body> 002 <div id="cube"> 003 <div class="front">1</div> 004 <div class="back">2</div> 005 <div class="right">3</div> 006 <div class="left">4</div> 007 <div class="top">5</div> 008 <div class="bottom">6</div> 009 </div> 010 </body>
More container!
We need to put all the above inside another invisible container so we can set the perspective. We’ll define it up as a section to show you don’t have to use a div.
001 <body> 002 <section class="container"> 003 <div id="cube"> 004 <div class="front">1</div> 005 <div class="back">2</div> 006 <div class="right">3</div> 007 <div class="left">4</div> 008 <div class="top">5</div> 009 <div class="bottom">6</div> 010 </div> 011 </section> 012 </body>
Make a cube
To make a cube we rotate/translate each face. Note how we rotate each face to point it in the right direction, then translate it to move it into place.
001 <style>
002 #cube .front {
003 transform: translateZ( 100px );
004 }
005 #cube .back {
006 transform: rotateX( -180deg ) translateZ( 100px );
007 }
008 #cube .right {
009 transform: rotateY( 90deg ) translateZ( 100px );
010 }
011 #cube .left {
012 transform: rotateY( -90deg ) translateZ( 100px );
013 }
014 #cube .top {100px );
015 transform: rotateX( 90deg ) translateZ( 100px );
016 }
017 #cube .bottom {
018 transform: rotateX( -90deg ) translateZ( 100px );
019 }
020 </style>
Colour in
Let’s add some colour. Using hsla for colours makes it easy to create a sequence of appealing and stylishly translucent shadings with copy, paste and editing.
001 #cube .front { background: hsla( 300, 100%, 50%, 0.7 ); }
002 #cube .back { background: hsla( 240, 100%, 50%, 0.7 ); }
003 #cube .right { background: hsla( 180, 100%, 50%, 0.7 ); }
004 #cube .left { background: hsla( 120, 100%, 50%, 0.7 ); }
005 #cube .top { background: hsla( 60, 100%, 50%, 0.7 ); }
006 #cube .bottom { background: hsla( 0, 100%, 50%, 0.7 ); }
Sizing objects
So far we have a cube with no sizes. Fix this by setting the sizes of the container, the cube div, and its faces.
001 .container {
002 width: 200px;
003 height: 200px;
004 position: relative;
005 margin: 0 auto 40px;
006 border: 1px solid #FFF;
007 }
008 #cube {
009 width: 100%;
010 height: 100%;
011 top: 100px; /* Offset from top of parent */
012 position: absolute;
013 }
014 #cube div {
015 display: block;
016 position: absolute;
017 width: 200px;
018 height: 200px;
019 border: 2px solid black;
020 }
Keep it together
You need to set the transform-style property to make sure 3D works properly. This is critically important when you’re transforming a group of child items!
001 #cube {
002 …
003 transform-style: preserve-3d; /*Keeps all the faces together. */
004 }
Set perspective
Now we can set up perspective. If we move an object relative to its parent, we have to adjust the perspective to compensate and set ‘margin 0 auto’ on all faces.
001 .container {
002 …
003 perspective: 1000px; /* A distant vanishing point */
004 perspective-origin: 50% 100%; /* Auto-offset perspective for child cube */
005 }
006 #cube div {
007 …
008 margin: 0 auto; Magic word that fixes perspective!
009 /* Without this the cube rotates around one edge –> bad… */
010 }
Set up on-hover
We want the cube to spin when we mouse over it, so we add a hover state with a 3D rotation. Spinning the cube automatically spins all of its faces.
001 #cube {
002 …
003 transition: transform 1s;
004 /* Set the transition duration */
005 }
006 #cube:hover {
007 transform: rotateX( 180deg ) rotateY(0deg);
008 /* Edit the X and Y rotations to create different end positions */
009 }
And we’re done
Hovering over the cube rotates it and reveals the back face – edit the hover transform to show other faces.
