3D flip animations with transforms and transitions

Smooth vertical, orizzontal and oblique 3D flip animations with jQuery or Css3

The Setup

The concept of this animations is simple, they are just two divs (.item-0 and .item-1) swapping each other with 3d animations.

<div class="item">
    <div class="item-0">
        <div class="content-0"></div>
    </div>
    <div class="item-1">
        <div class="content-1"></div>
    </div>
</div>

We give the visual styles to .item, .item-0, .item-1. Note that we set width and height to .item since we are using position:absolute for the items inside.

/* visual styles */
.item {
    width:212px;
    height:130px;
}
.item-0, .item-1 {
    position:absolute;
    width:212px;
    height:130px;
    border:1px solid #cecece;
    cursor:pointer;
    background:#ededed;
    background:-webkit-gradient(linear, left top, left bottom,color-stop(0%, #f4f4f4), color-stop(100%, #ededed));
    background:-moz-linear-gradient(top, #f4f4f4 0%, #ededed 100%);
    background:-ms-linear-gradient(top, #f4f4f4 0%, #ededed 100%);
}
.item:hover .item-0,
.item:hover .item-1 {
    border:1px solid #afafaf;
}

Then we set the contents, centering it with display:table and display:table-cell.

/* content styles */
.item-0, .item-1 {
    display:table;
}
.content-0, .content-1 {
    display:table-cell;
    vertical-align:middle;
    text-align:center;
}
.content-0:before {
    content:"Mouse over to animate";
    font-family:sans-serif;
    font-size:12px;
    letter-spacing:1px;
    color:#747474;
}
.content-1:before {
    content:"Hello there";
    font-family:sans-serif;
    font-size:12px;
    letter-spacing:1px;
    color:#747474;
}

Css Version

Alert
The Css version works only on browsers that support css3 transitions and transform3d.

The Animations

We do the animations setup by applying the starting styles to .item, .item-0 and .item-1. We also set the transitions, they will be executed when we mouseout.

/* animations setup and on mouse out */
.item {
    -webkit-perspective:800px;
    perspective:800px;
}
.item .item-0 {
    opacity:1;
    -webkit-perspective:800px;
    perspective:800px;
    -webkit-backface-visibility:hidden;
    backface-visibility:hidden;
    -webkit-transform:rotateX(0deg) rotateY(0deg) rotateZ(0deg);
    transform:rotateX(0deg) rotateY(0deg) rotateZ(0deg);
    -webkit-transition:all 0.8s cubic-bezier(0,.63,.41,.98) 0.8s;
    transition:all 0.8s cubic-bezier(0,.63,.41,.98) 0.8s;
}
.item .item-1 {
    opacity:0.6;
    -webkit-perspective:800px;
    perspective:800px;;
    -webkit-backface-visibility:hidden;
    backface-visibility:hidden;
    -webkit-transform:rotateX(0deg) rotateY(-90deg) rotateZ(0deg) scale(0.8);
    transform:rotateX(0deg) rotateY(-90deg) rotateZ(0deg) scale(0.8);
    -webkit-transition:all 0.8s cubic-bezier(1,0,.33,.33);
    transition:all 0.8s cubic-bezier(1,0,.33,.33);
}

Then we apply the animations when we :hover the .item.

/* animations on mouse hover */
.item:hover .item-0 {
    opacity:0.6;
    -webkit-transform:rotateX(0deg) rotateY(90deg) rotateZ(0deg) scale(0.8);
    transform:rotateX(0deg) rotateY(90deg) rotateZ(0deg) scale(0.8);
    -webkit-transition:all 0.4s cubic-bezier(1,0,.33,.33);
    transition:all 0.4s cubic-bezier(1,0,.33,.33);
}
.item:hover .item-1 {
    opacity:1;
    -webkit-transform:rotateX(0deg) rotateY(0deg) rotateZ(0deg) scale(1);
    transform:rotateX(0deg) rotateY(0deg) rotateZ(0deg) scale(1);
    -webkit-transition:all 0.4s cubic-bezier(0,.63,.41,.98) 0.4s;
    transition:all 0.4s cubic-bezier(0,.63,.41,.98) 0.4s;
}

Jquery Version

Alert
Remember to include the jQuery library and Minimit Anima plugin.

Fallback Animations

The jQuery version have fallback animations for browsers who don't support css transitions (like Internet Explorer 9). Minimit Anima have automatic fallback animations, and you can specify custom fallback animations with the anima2d method.

// example 3d animations for browsers that supports transitions and transform3d
path.anima3d({rotateX:"0deg", rotateY:"90deg", rotateZ:"0deg", scale:"0.8", opacity:0.6}, 400, bez11);

// example custom fallback animations for browsers that don't support transitions or transform3d
path.anima2d({scale:"0.8", opacity:0}, 400, bez11);

// example 3d animation with automatic fallback animations (scale and opacity)
path.anima({rotateX:"0deg", rotateY:"0deg", rotateZ:"0deg", scale:"1", opacity:1}, 400, bez21);

The Delay and Queue

The events use the jQuery queue system to make the animation more responsive.

$(this).clearQueue().delay(400).queue(function(){
    // animations here
    $(this).dequeue();
});

This code just gives a delay to code inside, while removing the delayed code from the queue. Read more about it in this article.

The Animations

The animation setup is needed to have proper starting animations.

// we save the bezier easing values convenience
var bez11 = "1,0,.33,.33";
var bez21 = "0,.63,.41,.98";

// animations setup
$(".item").css("perspective", "800px");
$(".item").find(".item-0").css("perspective", "800px").css("backface-visibility", "hidden").anima({rotateX:"0deg", rotateY:"0deg", rotateZ:"0deg"});
$(".item").find(".item-1").css("perspective", "800px").css("backface-visibility", "hidden").anima({rotateX:"0deg", rotateY:"-90deg", rotateZ:"0deg", scale:"0.8"}).anima2d({opacity:0});

Then we assign the animations to the mouseenter event.

// mouseenter animations
$(".item").on('mouseenter', function(e){ 
    $(this).clearQueue().delay(200).queue(function(){
        var path;
        // inside
        path = $(this).find(".item-0");
        path.clearAnima().stopAnima();
        path.anima3d({rotateX:"0deg", rotateY:"90deg", rotateZ:"0deg", scale:"0.8", opacity:0.6}, 400, bez11);
        path.anima2d({scale:"0.8", opacity:0}, 400, bez11);
        // outside
        path = $(this).find(".item-1");  
        path.clearAnima().stopAnima().delayAnima(400);
        path.anima({rotateX:"0deg", rotateY:"0deg", rotateZ:"0deg", scale:"1", opacity:1}, 400, bez21);
        $(this).dequeue();
    });
});

And to the mouseleave event.

// mouseleave animations
$(".item").on('mouseleave', function(e){
    $(this).clearQueue().delay(400).queue(function(){
        var path;
        // outside
        path = $(this).find(".item-1");
        path.clearAnima().stopAnima(false);
        path.anima3d({rotateX:"0deg", rotateY:"-90deg", rotateZ:"0deg", scale:"0.8", opacity:0.6}, 800, bez11);
        path.anima2d({scale:"0.8", opacity:0}, 800, bez11);
        // inside
        path = $(this).find(".item-0");
        path.clearAnima().stopAnima(false).delayAnima(800);
        path.anima({rotateX:"0deg", rotateY:"0deg", rotateZ:"0deg", scale:"1", opacity:1}, 800, bez21);
        $(this).dequeue();
    });
});