Look Inside
Hello there! Today I would like to show you how to create an amazing 3D rotation animation using CSS3 3D transforms and CSS3 animation properties, WITHOUT using JavaScript. You might, of course, can check out others amazing CSS3 effects like CSS3 background animation and pure CSS3 logo and icons.
The idea is to create a 3D ‘cube‘ gallery effects. Few cubes are located near each other with different images bind to cubes’ faces. These cubes will then rotate itself one by one with different timing and stop for awhile, and then rotate and stop again after this. The process will keep repeating itself. Check out the demo above to see it with your eyes!
The initial idea was inspired by CCSlider 3D cube effect, so I decide to create one similar but with CSS3 only. Anyway, you may go through the HTML markup and CSS style below for this CSS3 3D animation demo if you wish to know how it works. Otherwise you can just skip the part below and enjoy the cube rotation effect by CSS3 3D transforms.
[browser type=”cxsxx”]The demo only works on browsers that support CSS3 3D transforms, such as Chrome and Safari.[/browser]
Build a Cube
Let’s get it started with our core element – cube. This might not related to our demo, however it will be your fundamental before starting CSS3 3D transforms.

We all know that a basic cube consists of six faces, which are front, back, top, bottom, left and right. So we have to define these six faces using HTML element, and differential each other with different CSS classes.
<div id="viewContainer"> <div class="cube" > <div class="facefront"></div> <div class="faceback"></div> <div class="faceleft"></div> <div class="faceright"></div> <div class="facetop"></div> <div class="facebottom"></div> </div> </div>
However, these HTML elements won’t be able to become a cube automatically without help from CSS3 3D transforms.
/*--- Container for cube animation ---*/ #viewStage { -webkit-perspective: 1000px; -webkit-perspective-origin: 600px 600px; } /*--- Cube Style ---*/ .cube { position: relative; width: 300px; height: 300px; /* 3D Transforms attributes */ -webkit-transform-style: preserve-3d; -webkit-transform-origin: 50% 50%; } /* Each cube's face share same attributes */ .cube div { position: absolute; width: 300px; height: 300px; opacity:.7; -webkit-transform-origin: 50% 50%; } /*--- Cube faces color ---*/ .facefront { background-color: red; -webkit-transform: translateZ(150px); } .faceback { background-color: blue; -webkit-transform: rotateY(180deg) rotateZ(180deg) translateZ(150px); } .facetop { background-color: green; -webkit-transform: rotateX(90deg) translateZ(150px); } .facebottom { background-color: purple; -webkit-transform: rotateX(-90deg) translateZ(150px); } .faceleft { background-color: black; -webkit-transform: rotateY(90deg) translateZ(150px); } .faceright { background-color: yellow; -webkit-transform: rotateY(-90deg) translateZ(150px); }
The ‘viewStage
’ is the element in which our 3D animation takes place. All the elements inside will move and rotate in relation to this viewStage
, which itself will remain fixed to the page.
The perspective
attribute defines how far (Z-axis) the 3D element is placed from the view. The larger this value the less obvious the 3D effect.
If you paste the HTML and CSS markup above into your text editor and run it, you will see a colorful cube if your browser support of CSS3 3D transforms. Otherwise you will only able to see two rectangles with different color.
Right now, try modifying the perspective value and see the what happens to the cube.
Multiple Cubes
After the fundamental of creating a cube using CSS3 3D transforms, we will be going through the HTML and CSS markup of DEMO1. However, all the vendor prefixes will be excluded from the code, but you can still find them in the files.
The first step is to create few cubes and combine them into one big cube. We could achieve this by duplicates the cube markup above and styling it using different CSS. After then, name the cubes’ element with different ID.
<div id="viewStage"> <div id="cube1" class="cube" > <div class="facefront fb"></div> <div class="faceback fb"></div> <div class="faceleft lr"></div> <div class="faceright lr"></div> <div class="facetop tb"></div> <div class="facebottom tb"></div> </div> <div id="cube2" class="cube" > <div class="facefront fb"></div> <div class="faceback fb"></div> <div class="faceleft lr"></div> <div class="faceright lr"></div> <div class="facetop tb"></div> <div class="facebottom tb"></div> </div> <div id="cube3" class="cube" > <div class="facefront fb"></div> <div class="faceback fb"></div> <div class="faceleft lr"></div> <div class="faceright lr"></div> <div class="facetop tb"></div> <div class="facebottom tb"></div> </div> </div>
The CSS for combining these cubes are as below.
/*--- Container for cube animation ---*/ #viewStage { width: 450px; height: 300px; -webkit-perspective: 450px; -webkit-perspective-origin: 50% 50%; } /*--- Cube Style ---*/ .cube { position: relative; float: left; width: 150px; height: 300px; /* Cube Transforms attributes */ -webkit-transform-style: preserve-3d; -webkit-transform-origin: 50% 50%; } /*--- Cubes' Face Style ---*/ /* Face share attributes */ .cube div { background-color: #000; background-size: 450px 300px; position: absolute; -webkit-transform-origin: 50% 50%; -webkit-backface-visibility: hidden; } /* Face group fb - Front and Back */ .cube div.fb { width: 150px; height: 300px; } /* Face group tb - Top and Bottom */ .cube div.tb { width: 150px; height: 300px; } /* Face group lr - Left and Right */ .cube div.lr { width: 400px; height: 400px; } /* Individual Face attributes */ .facefront { -webkit-transform: translateZ(150px); } .facebck { -webkit-transform: rotateY(180deg) rotateZ(180deg) translateZ(150px); } .facetop { -webkit-transform: rotateX(90deg) translateZ(150px); } .facebottom { -webkit-transform: rotateX(-90deg) translateZ(150px); } .faceleft { -webkit-transform: rotateY(90deg) translateZ(0px); } .faceright { -webkit-transform: rotateY(-90deg) translateZ(150px); }
The -webkit-backface-visibility
attribute is used to specific whether or not the element should be visible when not facing the screen. The default value is visible.
Our next task is to bind the cubes’ faces with different images and positioning it according to the cubes location.
/*--- Cubes' faces ---*/ .facefront { background-image: url(../image1.jpg); -webkit-transform: translateZ(150px); } .facebck { background-image: url(../image3.jpg); -webkit-transform: rotateY(180deg) rotateZ(180deg) translateZ(150px); } .facetop { background-image: url(../image2.jpg); -webkit-transform: rotateX(90deg) translateZ(150px); } .facebottom { background-image: url(../image4.jpg); -webkit-transform: rotateX(-90deg) translateZ(150px); } .faceleft { -webkit-transform: rotateY(90deg) translateZ(0px); } .faceright { -webkit-transform: rotateY(-90deg) translateZ(150px); } /* Background position */ #cube1 div { background-position: 0 0; } #cube2 div { background-position: -150px 0; } #cube3 div { background-position: -300px 0; }
Cube Rotation
Now, we will make these cubes rotate itself automatically! In this case we use ‘rotation
‘ keyframes.
/*--- Cube Style ---*/ .cube { position:relative; float:left; width:150px; height:300px; /* Cube Transforms attributes */ -webkit-transform-style: preserve-3d; -webkit-transform-origin: 50% 50%; /* Cube Animation attributes */ -webkit-animation-name: rotation; -webkit-animation-timing-function: ease; -webkit-animation-iteration-count: infinite; -webkit-animation-duration: 15s; }
The CSS attributes above will generate an animation with duration of 15 seconds.
The ‘rotation
‘ keyframes for DEMO1 will be look like below. This keyframes will rotate the cube by quarter-circle and then pause it for few seconds, after that the cube will rotate and pause again.
/*-- Keyframes --*/ @-webkit-keyframes rotation { from, to { } 10%, 25% { -webkit-transform: rotateX(-90deg); } 35%, 50% { -webkit-transform: rotateX(-180deg); } 60%, 75% { -webkit-transform: rotateX(-270deg); } 85%, 100% { -webkit-transform: rotateX(-360deg); } }
You could actually perform more complicated rotation like DEMO2 or DEMO3 by amending the keyframes values. Download the files for more details about keyframes setting.
Enhancements
By the time now, you should able to see the cube rotation effect. However the effect looks rigid and inflexible. Hence we have to do some enhancements on this.
First, let’s make the rotation looks more attractive by adding some animation-delay
attribute to each cube.
/*-- Cubes z-index fix with animation delay --*/ #cube1 { z-index: 1; -webkit-animation-delay: 1s; } #cube2 { z-index: 2; -webkit-animation-delay: 1.2s; } #cube3 { z-index: 1; -webkit-animation-delay: 1.4s; }
Next, add more flexible easing instead of default easing.
/*--- Cube Style ---*/ .cube { position:relative; float:left; width:200px; height:400px; /* Cube Transforms attributes */ -webkit-transform-style: preserve-3d; -webkit-transform-origin: 50% 50%; /* Cube Animation attributes */ -webkit-animation-name: rotation; -webkit-animation-timing-function: cubic-bezier(0.6, -1, 0.4, 1.5); -webkit-animation-iteration-count: infinite; -webkit-animation-duration: 15s; }
Last, detect non-supported browsers using media query based on CSS3 3D transforms properties. If user browser doesn’t support CSS3 3D transform, display non-support text message, and vice versa.
<style> /*** Browsers fix ***/ .supported { display: none; } .unsupported { display: block; } /*** Webkit browser ***/ @media screen and (-webkit-transform-3d) { .supported { display: block; } .unsupported { display: none; } } </style> <div class="supported">Yes! Your browser DOES support CSS3 3D transforms.</div> <div class="unsupported">Oops! Your browser DOESN'T support CSS3 3D transforms.</div>
Final Thoughts
As you can see, currently not much browsers are support CSS3 3D transforms yet. Hence, you have to consider those non-supported browsers in order to use these new CSS3 attributes. For example, if you use Firefox to browse the demo page, you will see a sliding effect, but if you browse the demo page using IE, it will only shows a text message.
All of these checking mechanisms are simply done by CSS. Yes, of course you could build more complicated drawbacks and effects using JavaScript or jQuery. But I will left the part for you!