CSS3 2D and 3D Transform Techniques

Still using flash or gifs or such like to create some nice animations?….. Well those days are gone!! With the huge amount of css3 properties now available it is time to start showing them off whenever you get the chance.

CSS3 transform has been in the web for a fair amount of time now. Browsers like Mozilla, Google Chrome and Opera have support for CSS3 2D and 3D transform techniques.

So you want to learn a little, well that is why I am here! In this article you will learn:

  1. CSS3 2D Transform Techniques
  2. CSS3 3D Transform Techniques
  3. What is a Perspective?
  4. And many different transform functions

I have also prepared a couple of demos in which you can see them in action and perhaps inspect the code if your code is not quite working out, the deoms included are:

  1. A 3D Card Flip
  2. A 3D Cube or a dice

The first question you might wonder is why do we need CSS3 transforms for animations and graphics? Well, the answer is very simple, faster web pages!

CSS animations are extremely light when compared with heavy GIF images and Flash content or the like. Then to add to it, Google does not rate Flash content highly in terms of SEO. Robots and search engines can easily access these animations and could possibly help with your site ranking.

Understanding CSS3 2D Transform

CSS3 2D transform gives you more freedom to decorate and animate HTML components. You have even more features to decorate text and more animation options for decorating div elements. CSS3 2D transform contains some basic functions like below:

  • translate()
  • rotate()
  • scale()
  • skew()
  • matrix()

Translate

Using the translate() function, you can move the div and text from their original position to any x-y co-ordinate without affecting other HTML components. For example:

div{
    transform: translate(20px,20px);
}

The above code translates the div element 20px in x-direction and 20px in the y-direction.

demo1

NOTE: x-y coordinates positioning in browsers is not same as used in geometry. A positive x value implies moving the object towards the right direction while a positive y value means moving it towards the bottom in y-direction. (0,0) co-ordinates refer to the top left corner of the browser.

For browsers like Opera, Chrome and older Firefox, you have to use –webkit-, -moz-, and –o- prefixes to the transform property. The CSS3 transform is not fully accepted by all browsers, but major browsers do support them with one of the above vendor provided prefixes.

Rotate

The rotate transform function rotates a specified HTML element to a given degree. The rotation is clockwise and starts from 0deg to 360deg. The rotation is done in the x-y plane.

div{
    transform: rotate(30deg);
}
<img class="alignnone size-full wp-image-2924" alt="demo2" src="http://shhdesign.co.uk/blog/wp-content/uploads/2013/01/demo2.png" width="602" height="327" />

Scale

As the name suggests, it scales the old div to the new size as specified. This scaling takes place in both x and y direction. You can control the amount of scaling by specifying values, as parameters, to scale() function.

div{
    transform: scale(2,4);
}

demo3

Skew

When a skew transform function is applied to an element, the element bends to a specified amount as provided in the parameters list. You have to specify the angle value for x-direction as well as for the y-direction.

div{
    transform: skew(30deg,20deg);
}
<img class="alignnone size-full wp-image-2926" alt="demo4" src="http://shhdesign.co.uk/blog/wp-content/uploads/2013/01/demo4.png" width="602" height="336" />

Matrix

The work of matrix transform function is to combine all the above 2D transform function into one property. The values are in the form of linear transformation matrix.

div{
    transform: matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
}

figure4a

CSS3 3D Transform

Now that you have an understanding of the basics of 2D transformation, understanding 3D transformation will not be difficult to step up to. 3D transform includes Z-axis transformation of the HTML elements. Let’s go through each of the new properties used in 3D transformation.

  • translate3d(&lt;translation-value&gt;, &lt;translation-value&gt;, &lt;length&gt;) : it defines a 3D translation. It takes three parameters x, y and z values. The z value specifies the translation in the Z-axis.
  • translateZ(&lt;length&gt;) : To define the translation only in the Z-direction, use this transform function. It works similar to translateX() and translateY().
  • scale3d(&lt;number&gt;, &lt;number&gt;, &lt;number&gt;) : This function does the scaling in all the three dimensions. It takes three parameters as sx, sy and sz. Each value defines scaling in the respective direction.
  • scaleZ(&lt;number&gt;) : Just like the translate() function, we also have scaleZ() function which defines scaling only in one direction ie Z-direction. We also have scaleX() and scaleY() functions which also work similar to scaleZ() but in their respective directions.
  • rotate3d(&lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;angle&gt;) : It rotates a single HTML element by the specified angle provided in the last parameter in the [tx, ty, tz] vector specified by the first three numbers.
  • rotateX(&lt;angle&gt;), rotateY(&lt;angle&gt;) and rotateZ(&lt;angle&gt;) take only a single angle value to rotate in the respective axis.

Note: rotate3d(1,0,0,30deg) is equal to rotateX(30deg), rotate3d(0,1,0,30deg) is equal to rotateY(30deg) and rotate3d(0,0,1,30deg) is equal to rotateZ(30deg).

Perspective

The main part of the 3D Transform using CSS is the perspective. To activate a 3D space to make 3D transformation, you need to active it. This activation can be done in two ways as follows:

transform: perspective(500px);

or

perspective: 500px;

The functional notation is used to activate a single element whereas the second notation is used to apply perspective to multiple elements at the same time.

Transform Style

This is another important property in the 3D space. It takes two values: preserve-3d or flat. When the transform style value is preserve-3d then it tells the browser that the children element should also be positioned in the 3D space. On the other hand when the value of this property is flat, it indicates that children are present on the plane of the element itself.

Let’s start working

In this section, we will try to learn how to activate the 3D space and apply 3D transform functions as stated above. Let’s create a blue square figure and then rotate it by 30 degrees on the Y axis.

HTML

&lt;section id="blue"&gt;
    &lt;div&gt;&lt;/div&gt;
&lt;/section&gt;

CSS

/* styling a container of size 200px X 200px that will contain the object */
.container{
    width:200px;
    height:200px;
    margin:40px auto;
    position:relative;
}
/* activating the 3D space */
#blue{
    perspective: 600px;
}
/* coloring the box and rotating it by 30 degrees in the 3D space */
#blue .box{
    background:blue;
    transform: rotateY(30deg);
    -moz- transform: rotateY(30deg);
    -webkit- transform: rotateY(30deg);
    -o- transform: rotateY(30deg);
}

demo5

Similarly you can apply different translate(), scale() and rotate() functions to the above figure and see how the figure orientation changes. Below that shows a translateZ()  transformation.

demo6

CSS3 3D Transform Demos

1) Card Flip

Now that we have understood the 2D and 3D transformation basics, we will make some practical demos and see how we can use them. I will show you how to make a card flip animation using CSS3 3D transform. The card has my logo on the front side and my tag line on the back. The demo will flip between these over a white box with a grey outline as shown below.

demo7 demo8 demo9

HTML

&lt;section&gt;
    &lt;div id="card"&gt;
    &lt;figure&gt;&lt;/figure&gt;
    &lt;figure&gt;&lt;/figure&gt;
&lt;/div&gt; &lt;/section&gt;
&lt;a href="#"&gt;flip it!&lt;/a&gt;

CSS

/* Design container */
.container {
    width: 250px;
    height: 250px;
    position: relative;
    margin: 40px auto;
    border: 1px solid #999999;
    -webkit-perspective: 600px;
    -moz-perspective: 600px;
    -o-perspective: 600px;
    perspective: 600px;
}

The container is a square and each side measures 250px. We have also given a margin style to position the container to the center of the screen. To activate the 3D space we have also set the prospective property to 600px. As this is the main container.

CSS

/* styling card element */
#card {
    width: 100%;
    height: 100%;
    position: absolute;
    -webkit-transition: -webkit-transform 1s;
    -moz-transition: -moz-transform 1s;
    -o-transition: -o-transform 1s;
    transition: transform 1s;
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    -o-transform-style: preserve-3d;
    transform-style: preserve-3d;
}

Since height and width are set to 100%, the card div takes the dimensions of the parent container element. We have defined how long the transformation should take place with the transition property. It is set to 1s to animate the flipping for 1 second. The transform-style property makes sure that the children elements of this card div also have their 3D spaces activated. By default if the parent element’s 3D space is activated then only its direct children inherit the 3D activation. So in this example transform-style tells the children of the child div to inherit the 3D activation.

CSS

/* styling figure elements */
#card figure {
    display: block;
    height: 100%;
    width: 100%;
    position: absolute;
    margin:0px;
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -o-backface-visibility: hidden;
    backface-visibility: hidden;
}

We have set backface-visibility property as hidden so the card is opaque and not transparent. You can also try setting it to transparent and see what effect you get.

CSS

#card .front {
    background: url('card1.png');
}
#card .back {
    background: url('card2.png');
    -webkit-transform: rotateY( 180deg );
    -moz-transform: rotateY( 180deg );
    -o-transform: rotateY( 180deg );
    transform: rotateY( 180deg );
}

We have used two images, card1.png and card2.png, as the background of the front figure and back figure.

Now that we have almost set everything, we need another class called “flipped” and set the transform property. This class will be set dynamically on the client side using any client-side scripting. I have used jQuery in this case. The “flipped” class styles are set as below:

CSS

#card.flipped {
    -webkit-transform: rotateY( 180deg );
    -moz-transform: rotateY( 180deg );
    -o-transform: rotateY( 180deg );
    transform: rotateY( 180deg );
}

To run the animation, add an extra HTML link tag or a button and set the click event as follows:

jQuery Code

$(document).ready(function(){
    $("a").click(function(){
        $("#card").toggleClass("flipped");
    });
});

As you can see, we have used the click property of the link and have set a callback function. The task of the function is to toggle the class of the card div to “flipped”.

Congrats! You’ve made the card flip animation. Go to the browser and see the animation. Pretty darn tootin neat right!?

Live Demo

2) A 3D Rotating Cube

Let’s try something a little more complicated if your strong enough? This time we will have six faces instead of only two. We will style each face, set them to the proper orientation and finally animate. Each face of the cube will show the face number.
demo10demo11 demo12 demo14

HTML

&lt;section&gt;
    &lt;div id="cube"&gt;
        &lt;figure&gt;1&lt;/figure&gt;
        &lt;figure&gt;2&lt;/figure&gt;
        &lt;figure&gt;3&lt;/figure&gt;
        &lt;figure&gt;4&lt;/figure&gt;
        &lt;figure&gt;5&lt;/figure&gt;
        &lt;figure&gt;6&lt;/figure&gt;
    &lt;/div&gt;
&lt;/section&gt;
&lt;a href=”#”&gt;Rotate it!&lt;/a&gt;

Now we have the basic HTML structure of the cube. The main div, “cube” has six child “figure” elements for each side of the cube. Let’s start styling each of them.

CSS

/* First the container styles */
.container {
    width: 200px;
    height: 200px;
    position: relative;
    -webkit-perspective: 1000px;
    -moz-perspective: 1000px;
    -o-perspective: 1000px;
    perspective: 1000px;
    margin: 0 auto 40px;
    border: 1px solid #CCC;
}

Mark that we have activated the 3D space using the perspective property.

CSS

#cube {
    width: 100%;
    height: 100%;
    position: absolute;
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    -o-transform-style: preserve-3d;
    transform-style: preserve-3d;
    -webkit-transform: translateZ( -100px );
    -moz-transform: translateZ( -100px );
    -o-transform: translateZ( -100px );
    transform: translateZ( -100px );
    -webkit-transition: -webkit-transform 0.5s;
    -moz-transition: -moz-transform 0.5s;
    -o-transition: -o-transform 0.5s;
    transition: transform 0.5s;
}

For the cube, we have used the same preserve-3d to transform property as we did in the card flip example. One more thing which we did in this example was translating the whole cube -100px in the z-direction. Later in this example we will see that, the front facing side of the cube 100px in the z-direction is always translated 100px to the front. So, in order to make the text appear hazy, we have moved the whole cube -100px back.

CSS

#cube figure {
    width: 196px;
    height: 196px;
    display: block;
    position: absolute;
    border: 2px solid black;
    line-height: 196px;
    font-size: 120px;
    font-weight: bold;
    color: white;
    text-align: center;
    margin:0px;
}

The above styles will set the general CSS of each side. They should be square in dimensions and have a black border of 2px.

CSS

/* Applying a unique color to each face */
#cube .front  { background: hsla(   0, 100%, 50%, 0.7 ); }
#cube .back   { background: hsla(  60, 100%, 50%, 0.7 ); }
#cube .right  { background: hsla( 120, 100%, 50%, 0.7 ); }
#cube .left   { background: hsla( 180, 100%, 50%, 0.7 ); }
#cube .top    { background: hsla( 240, 100%, 50%, 0.7 ); }
#cube .bottom { background: hsla( 300, 100%, 50%, 0.7 ); }

CSS

/* Giving the desired orientation to each side of the cube */
#cube .front  {
    -webkit-transform: rotateY(   0deg ) translateZ( 100px );
    -moz-transform: rotateY(   0deg ) translateZ( 100px );
    -o-transform: rotateY(   0deg ) translateZ( 100px );
    transform: rotateY(   0deg ) translateZ( 100px );
}
#cube .back   {
    -webkit-transform: rotateX( 180deg ) translateZ( 100px );
    -moz-transform: rotateX( 180deg ) translateZ( 100px );
    -o-transform: rotateX( 180deg ) translateZ( 100px );
    transform: rotateX( 180deg ) translateZ( 100px );
}
#cube .right  {
    -webkit-transform: rotateY(  90deg ) translateZ( 100px );
    -moz-transform: rotateY(  90deg ) translateZ( 100px );
    -o-transform: rotateY(  90deg ) translateZ( 100px );
    transform: rotateY(  90deg ) translateZ( 100px );
}
#cube .left   {
    -webkit-transform: rotateY( -90deg ) translateZ( 100px );
    -moz-transform: rotateY( -90deg ) translateZ( 100px );
    -o-transform: rotateY( -90deg ) translateZ( 100px );
    transform: rotateY( -90deg ) translateZ( 100px );
}
#cube .top    {
    -webkit-transform: rotateX(  90deg ) translateZ( 100px );
    -moz-transform: rotateX(  90deg ) translateZ( 100px );
    -o-transform: rotateX(  90deg ) translateZ( 100px );
    transform: rotateX(  90deg ) translateZ( 100px );
}
#cube .bottom {
    -webkit-transform: rotateX( -90deg ) translateZ( 100px );
    -moz-transform: rotateX( -90deg ) translateZ( 100px );
    -o-transform: rotateX( -90deg ) translateZ( 100px );
    transform: rotateX( -90deg ) translateZ( 100px );
}

Now we have a 3D non-rotating cube ready with us. Finally we have to write a transition style for each side which we will implement by applying the right class using jQuery dynamically.

CSS

#cube.show-front  {
    -webkit-transform: translateZ( -100px ) rotateY(    0deg );
    -moz-transform: translateZ( -100px ) rotateY(    0deg );
    -o-transform: translateZ( -100px ) rotateY(    0deg );
    transform: translateZ( -100px ) rotateY(    0deg );
}
#cube.show-back   {
    -webkit-transform: translateZ( -100px ) rotateX( -180deg );
    -moz-transform: translateZ( -100px ) rotateX( -180deg );
    -o-transform: translateZ( -100px ) rotateX( -180deg );
    transform: translateZ( -100px ) rotateX( -180deg );
}
#cube.show-right  {
    -webkit-transform: translateZ( -100px ) rotateY(  -90deg );
    -moz-transform: translateZ( -100px ) rotateY(  -90deg );
    -o-transform: translateZ( -100px ) rotateY(  -90deg );
    transform: translateZ( -100px ) rotateY(  -90deg );
}
#cube.show-left   {
    -webkit-transform: translateZ( -100px ) rotateY(   90deg );
    -moz-transform: translateZ( -100px ) rotateY(   90deg );
    -o-transform: translateZ( -100px ) rotateY(   90deg );
    transform: translateZ( -100px ) rotateY(   90deg );
}
#cube.show-top    {
    -webkit-transform: translateZ( -100px ) rotateX(  -90deg );
    -moz-transform: translateZ( -100px ) rotateX(  -90deg );
    -o-transform: translateZ( -100px ) rotateX(  -90deg );
    transform: translateZ( -100px ) rotateX(  -90deg );
}
#cube.show-bottom {
    -webkit-transform: translateZ( -100px ) rotateX(   90deg );
    -moz-transform: translateZ( -100px ) rotateX(   90deg );
    -o-transform: translateZ( -100px ) rotateX(   90deg );
    transform: translateZ( -100px ) rotateX(   90deg );
}

Finally we are ready to write the callback function using jQuery. The callback will triggered once the “Rotate!” link is clicked.

jQuery

$(document).ready(function(){
    var ctr=0;
    var panel="";
        $("a").click(function(){
            ctr++;
            if(ctr==1){
                $("#cube").toggleClass("show-back");
                $("#cube").removeClass(panel);
                panel="show-back";
            }
            if(ctr==2){
                $("#cube").toggleClass("show-right");
                $("#cube").removeClass(panel);
                panel="show-right";
            }
            if(ctr==3){
                $("#cube").toggleClass("show-left");
                $("#cube").removeClass(panel);
                panel="show-left";
            }
            if(ctr==4){
                $("#cube").toggleClass("show-top");
                $("#cube").removeClass(panel); panel="show-top";
            }
            if(ctr==5){
                $("#cube").toggleClass("show-bottom");
                $("#cube").removeClass(panel);
                panel="show-bottom";
            }
            if(ctr==6){
                $("#cube").toggleClass("show-front");
                $("#cube").removeClass(panel);
                panel="show-front"; ctr=0;
            }
        });
});

Live Demo

Well that shoud do you for now, you have learnt some pretty cool stuff and have the foundations to go and create some weird and whacky, wonderful pieces of work.

Think about it you could uses these techniques to create many number of things such as a slider, an image carousel, an animated image album like Google+ photo album, etc etc.

So get playing!