CSS3 3D Box With Shadows - css

I'm making a notification system. I want this notification to show up like a box that turns, somewhat like some notifications in iOS that the top of the screen rotates like a cube.
Now, the front and back of the cube should be transparant/same color as background. When it turns, a shadow should fall over the sides that are not parallel to the front of the viewer, as if there is a lamp shining on the box. Can this be done?
To make more clear: Since the front & back of the box are the same as the background-color, when turning the box it wouldn't seem like a box turning but rather a slice of paper that rotates into place. So what I want is that faces of the cube get a shadow to it depending on their angle as opposed to the viewer.
For example, once the front-face (which you can't really see since it's the same color as the background-color) is rotated 1 degree, it should get a little darker/lighter. Another degree, a little more. So that the true color of the face is only shown when it's directly parallel to the user. This will create the illusion of there being a box, rather than a sliver of paper.
I'm using this tutorial on the cube: http://desandro.github.io/3dtransforms/docs/cube.html
Here is a fiddle: http://jsfiddle.net/BqJMW/3/
Another issue is that currently the text seems a bit stretched, if you know what I mean. Normally the transform: translateZ(-25px); (see code below) on the #cube should solve this, but it still seems out of proportion.
CSS
body {
background: #ebebeb;
}
.container {
width: 200px;
height: 50px;
position: relative;
-webkit-perspective: 1000px;
perspective: 1000px;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
-webkit-transform: translateZ(-25px);
transform: tranlateZ(-25px);
}
#cube figure {
margin:0;
display: block;
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#cube .front {
background: transparant;
-webkit-transform: translateZ(25px);
transform: translateZ(25px);
}
#cube .top {
background: green;
-webkit-transform: rotateX(-90deg) translateZ(25px);
transform: rotateX(-90deg);
}
#cube .back {
background: transparant;
-webkit-transform: rotateX(180deg) translateZ(25px);
transform: rotate(180deg);
}
#cube.show-front {
-webkit-transform:translateZ(-25px);
tranform: translateZ(-25px);
}
#cube.show-top {
-webkit-transform: translateZ(-25px);
transform: translateZ(-25px);
-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);
}
#cube.show-back {
-webkit-transform: translateZ(-25px);
transform: translateZ(-25px);
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
HTML
<section class="container">
<div id="cube">
<figure class="front">Front</figure>
<figure class="top">Your notification</figure>
<figure class="back">Back</figure>
</div>
</section>

By setting the initial colour of the notification face to a darker version of the final color, we can use a CSS3 transition on the color attribute of that face to animate it to a lighter colour as the face is rotated.
I've added a new class with the lighter "green" that will be added/removed to/from the notification face and changed the initial color added a new transition to #cube .top.
I've also corrected some typos in the CSS (tranform → transform, transparant → transparent) and removed the duplicate -webkit-transform:translateZ(-25px); and non-prefixed version from the .show-front|top|back classes as they are being overridden in the same class.
Lastly, since the notification face is translated towards the viewer by 25px the text looks blurry (on Chrome). This seems to go away by removing the -webkit-perspective: 1000px; for me. I'll leave that up to you if you want to remove it.
See the demo or following code:
CSS
body {
background: #ebebeb;
}
.container {
width: 200px;
height: 50px;
position: relative;
-webkit-perspective: 1000px;
perspective: 1000px;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
-webkit-transform: translateZ(-25px);
transform: translateZ(-25px);
}
#cube figure {
margin:0;
display: block;
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#cube .front {
background: transparent;
-webkit-transform: translateZ(25px);
transform: translateZ(25px);
}
#cube .top{
background-color:darkgreen;
-webkit-transform: rotateX(-90deg) translateZ(25px);
transform: rotateX(-90deg);
-webkit-transition:background-color .5s;
}
#cube .top.show {
background-color:green;
}
#cube .back {
background: transparent;
-webkit-transform: rotateX( 180deg ) translateZ(25px);
transform: rotate(180deg);
}
#cube.show-front{
}
#cube.show-top {
-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);
}
#cube.show-back {
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
JavaScript
$('.showfront').click(function () {
$('.top').removeClass('show');
$('#cube').removeClass().addClass('show-front');
});
$('.showtop').click(function () {
$('.top').addClass('show');
$('#cube').removeClass().addClass('show-top');
});
$('.showback').click(function(){
$('.top').removeClass('show');
$('#cube').removeClass().addClass('show-back');
});

Related

Zoom-in Zoom-out img automatically using css only

I have a working demo. just hover the img and there is the effect I want to have.
http://jsfiddle.net/jxgjhzer/1/
As you can see in css file, I don't use any css animation.
Just using CSS transform, I want my img to achieve same effect without hovering it. It should happen automatically.
So how to zoom-in and zoom-out automatically (without animation if possible)?
Code goes here:
.galleryImg{
height:150px;
width:100%;
transform-origin: 50% 50%;
transition: transform 30s linear;
}
.galleryImg:hover{
transform: scale(2) rotate(0.1deg);
}
that's very simple. you can see DEMO on this link on jsfiddle.net
<div class="cardcontainer">
<img class="galleryImg" src="https://www.google.com/logos/doodles/2014/2014-winter-olympics-5710368030588928-hp.jpg">
</div>
#keyframes zoominoutsinglefeatured {
0% {
transform: scale(1,1);
}
50% {
transform: scale(1.2,1.2);
}
100% {
transform: scale(1,1);
}
}
.cardcontainer img {
animation: zoominoutsinglefeatured 1s infinite ;
}
use animation
.galleryImg{
height:150px;
width:100%;
animation:move 3s infinite ease-in-out;
}
#keyframes move{
0%{
transform: scale(1) rotate(0deg);
}
100%{
transform: scale(2) rotate(0.1deg);
}
}
The below css code will help you out for zoom out effect on hover the particular image. Try this code its very useful to you
figure {
width: 300px;
height: 200px;
margin: 0;
padding: 0;
background: #fff;
overflow: hidden;
}
figure:hover+span {
bottom: -36px;
opacity: 1;
}
.hover04 figure img {
width: 400px;
height: auto;
-webkit-transition: .3s ease-in-out;
transition: .3s ease-in-out;
}
.hover04 figure:hover img {
width: 300px;
}
Refer the html code here.
<div class="hover04 column">
<div>
<figure><img src="1.jpeg" /></figure>
<span>Hover Text</span>
</div>
</div>

Animating ng-include flip

I'm new to css transitions and am experimenting with trying to animate the transition between two sub templates that I am including in my angularjs project using ng-include.
I am attempting to replicate the effect seen here (click on the flip option in the dropdown). However I can't seem to get the newly added template to animate its entrance correctly. The leaving template 'flips' out but the entering template just appears rather than 'flipping' in.
My page has the following basic structure:
<div class="content">
<div class="page flip" ng-include="something"></div>
</div>
I am using the following css:
.content {
-webkit-perspective: 600px;
perspective: 600px;
position:relative;
}
.page{
position:absolute;
background:red;
}
.content .page.flip {
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
.content .page.flip.ng-enter {
-webkit-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
.content .page.flip.ng-enter-active {
-webkit-transform: rotateX(0deg);
transform: rotateX(0deg);
}
.content .page.flip.ng-leave {
-webkit-transform: rotateX(0deg);
transform: rotateX(0deg);
}
.content .page.flip.ng-leave-active {
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
I've made a plunker by adapting the ng-include demo from angular website here to illustrate problem.
Can anyone point me to where I am going wrong?

3d Navbar That Rotates

I'm trying to create a 3d navbar using pure CSS with transforms, transitions and perspective.
Here is my code:
.navbar-fixed-bottom {
background: transparent;
}
.navbar-perspective {
width: 100%;
height: 100%;
position: relative;
-webkit-perspective: 1100px;
-moz-perspective: 1100px;
perspective: 1100px;
-webkit-perspective-origin: 50% 0;
-moz-perspective-origin: 50% 0;
perspective-origin: 50% 0;
}
.navbar-perspective > div {
margin: 0 auto;
position: relative;
text-align: justify;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
height: 50px;
font-size:20px;
}
.navbar-primary {
background-color: #cccccc;
z-index: 2;
-webkit-transform-origin: 0% 100%;
-moz-transform-origin: 0% 100%;
transform-origin: 0% 100%;
}
.navbar .navbar-secondary,
.navbar .navbar-tertiary {
background-color: #bfbfbf;
width: 100%;
-webkit-transform-origin: 0% 0%;
-moz-transform-origin: 0% 0%;
transform-origin: 0% 0%;
z-index: 1;
-webkit-transform: rotateX(-90deg);
-moz-transform: rotateX(-90deg);
transform: rotateX(-90deg);
-webkit-transition: top 0.5s;
-moz-transition: top 0.5s;
transition: top 0.5s;
position: absolute;
top: 0;
}
.navbar .navbar-tertiary {
background-color: #b3b3b3;
}
.navbar-rotate-primary {
height: 50px;
}
.navbar-rotate-primary .navbar-primary {
-webkit-transform: translateY(0%) rotateX(0deg);
-moz-transform: translateY(0%) rotateX(0deg);
transform: translateY(0%) rotateX(0deg);
}
.navbar-rotate-primary .navbar-secondary,
.navbar-rotate-primary .navbar-tertiary {
top: 100%;
-webkit-transition: -webkit-transform 0.5s;
-moz-transition: -moz-transform 0.5s;
transition: transform 0.5s;
-webkit-transform: rotateX(-90deg);
-moz-transform: rotateX(-90deg);
transform: rotateX(-90deg);
}
.navbar-rotate-secondary,
.navbar-rotate-tertiary {
height: 50px;
}
.navbar-rotate-secondary .navbar-primary,
.navbar-rotate-tertiary .navbar-primary {
-webkit-transform: translateY(-100%) rotateX(90deg);
-moz-transform: translateY(-100%) rotateX(90deg);
transform: translateY(-100%) rotateX(90deg);
}
.navbar-rotate-secondary .navbar-secondary,
.navbar-rotate-tertiary .navbar-secondary {
top: 100%;
-webkit-transition: -webkit-transform 0.5s;
-moz-transition: -moz-transform 0.5s;
transition: transform 0.5s;
-webkit-transform: rotateX(0deg) translateY(-100%);
-moz-transform: rotateX(0deg) translateY(-100%);
transform: rotateX(0deg) translateY(-100%);
}
.navbar-rotate-secondary-fallback .navbar-primary,
.navbar-rotate-tertiary-fallback .navbar-primary {
display: none;
}
.navbar-rotate-tertiary .navbar-secondary {
-webkit-transform: translateY(-100%) rotateX(90deg);
-moz-transform: translateY(-100%) rotateX(90deg);
transform: translateY(-100%) rotateX(90deg);
}
.navbar-rotate-tertiary .navbar-tertiary {
top: 100%;
-webkit-transition: -webkit-transform 0.5s;
-moz-transition: -moz-transform 0.5s;
transition: transform 0.5s;
-webkit-transform: rotateX(0deg) translateY(-100%);
-moz-transform: rotateX(0deg) translateY(-100%);
transform: rotateX(0deg) translateY(-100%);
}
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<nav id="navigation-bottom" class="navbar navbar-fixed-bottom">
<div class="navbar-perspective">
<div class="navbar-primary">
Rotate To Face 2
</div>
<div class="navbar-secondary">
Rotate To Face 3
</div>
<div class="navbar-tertiary">
Rotate Back To Face 1
</div>
</div>
</nav>
</body>
</html>
I've got the first two faces to rotate properly using a 3d effect, but the third face does not look right. You will notice as you rotate from second to third that the top does not rotate correctly and looks flat.
Any help is greatly appreciated.
Fiddle with a flipping box
This is vastly different from where you started, but let me post my CSS and show you the fiddle, and then I'll edit in a longer explanation of how and why this works:
 
HTML
<section class="container">
<nav id="nav-box" class="show-front">
<div class="front">
Show Bottom
</div>
<div class="bottom">
Show Back</div>
<div class="back">
Show Top</div>
<div class="top">
Show Front</div>
</nav>
</section>
 
CSS
.container {
position: relative;
perspective: 1000px;
transform: scale(0.95);
}
#nav-box {
width: 100%;
height: 50px;
position: absolute;
transform-origin: center center;
transform-style: preserve-3d;
transition: transform 0.5s;
}
#nav-box div {
width: 100%;
height: 50px;
display: block;
position: absolute;
transition: background-color 0.5s;
}
#nav-box .front { transform: rotateX( 0deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box .back { transform: rotateX( 180deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box .top { transform: rotateX( 90deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box .bottom { transform: rotateX( -90deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box.show-front { transform: rotateY( 0deg ); }
#nav-box.show-front .bottom { background-color: #a0a0a0; }
#nav-box.show-front .top { background-color: #e0e0e0; }
#nav-box.show-back { transform: rotateX( -180deg ); }
#nav-box.show-back .bottom { background-color: #e0e0e0; }
#nav-box.show-back .top { background-color: #a0a0a0; }
#nav-box.show-top { transform: rotateX( -90deg ); }
#nav-box.show-top .front { background-color: #a0a0a0; }
#nav-box.show-top .back { background-color: #e0e0e0; }
#nav-box.show-bottom { transform: rotateX( 90deg ); }
#nav-box.show-bottom .front { background-color: #e0e0e0; }
#nav-box.show-bottom .back { background-color: #a0a0a0; }
 
Explanation of the HTML/CSS
Setting up our box
You started thinking about this the wrong way, I hate to say. You approached this as "How can I treat these four sides like a box" rather than "How can I make a box in CSS?"
So let's learn how to make a box.
First, we establish a box container. Since this is a navigation box, let's call it nav-box. All the transforms we apply (save for the shading, which we'll get to later) will be done on our nav-box.
The rules on our nav-box will determine how it behaves as an object. Let's discuss two in particular: transform-origin and transform-style
transform-origin defaults to center center, but I wanted to call it out here. This is basically going to tell our box: Hey, we need you to pivot around your absolute center. If we set this up as transform-origin: center bottom' it would look like the box is spinning around its bottom edge. center top` and it would spin around its top edge. I don't think that's what you want, though.
transform-style needs to be set to preserve-3d. What this does is instruct the browser to not fuss with the elements with transform underneath it. Other options include flat which tells the browser to ignore rotates underneath it. The reason we want to set preserve-3d on our nav-box here is to ensure the transforms we applied to the box sides are preserved when we transform the parent. Neat stuff, huh?
Setting up our sides
We're setting our sides as children of our nav-box and just positioning them in the order that they should be in using rotateX:
0 rotation for the front
180deg for the back
-90deg for the bottom
90deg for the top
We could also set a left and right side right now with .left { transform: rotateY(-90deg); } .right { rotateY(90deg); }. Note that we used the Y axis for those two examples.
Secondly, we set a translateZ value of 25px. So what the hell is this doing? It's telling our boxes they need to move 25px from the center of the parent relative to their respective rotations. Why did we choose 25px? Because it's exactly half the height of each of our boxes. This means that it will flush up nicely with the sides at either edge.
And then the fun part:
We shade the boxes based on their position and what is facing the screen. The background colors are relative to what side of the box we're showing with show-front, show-back, etc. The side on the bottom gets darker, the side on the top gets lighter. I just liked that – totally not necessary to accomplish this task but makes it look a little more realistic.
Hope that helps!
 
Update for IE
Fiddle Example
So, there's not much pretty about this once we get through fixing it up for IE, but here it is. All preserve-3d is doing is applying the transforms for you when we rotate a container, instead of flattening them. If we can't use preserve-3d, we have to calculate based on the amount of total rotation.
This solution does that. I won't go as in-depth on this one, rather than to highlight how much more JavaScript this requires, and to highlight the .rewind class:
#nav-box.rewind div {
backface-visibility: hidden;
}
Because we have to manually rewind this solution, we'll have to prevent the z-index reordering to be applied at the wrong times. That's where backface-visibility comes in.
Example showing depth in IE
Another example without the need for the rewind class
Hope that solves IE for you.
First of all, thank you to all that commented and answered to this question, especially Josh!
Josh, your example works perfectly for browsers that support preserve-3d. The update you posted without preserve-3d appears flat on IE so it was still not perfected for all browsers.
After three days of headaches, I realized the problem. The origin of the sides was not being set correctly. The sides need to rotate around a point that is half way in on the Z axis.
Once I've updated the origin to :
transform-origin: 25px 25px -25px;
Once this was correct, all you really need to do is update the rotation of the object. No need to use any transformation of the X,Y,Z coordinates.
Here's the fiddle and the solution for a 3D Navigation bar that rotates and works for all browsers including IE10+.
http://jsfiddle.net/tx0emcxe/

How to Flip a div and show different sized content on front and back?

I'm trying to create a div "flipcard" element that contains different sized content on the front and back.
The HTML:
<div class="flipcard">
<div class="face front">Front</div>
<div class="face back">Back ... put some long text here ... </div>
</div>
The Javascript just adds and removes a "flipped" class:
$('.flipcard').click(function(e) {
var $card = $(this);
if ($card.hasClass("flipped")) $card.removeClass('flipped');
else $card.addClass('flipped');
});
All the magic happens in the CSS:
.flipcard {
margin: 1em auto;
width: 80%;
/* I don't want to set the height because
we don't know the size of the content */
border: solid 1em white;
border-radius: 0.5em;
font-family: Georgia;
-webkit-perspective: 800;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
cursor: pointer;
}
.flipcard:hover {
box-shadow: 0 0 1em black;
}
.flipcard.flipped {
-webkit-transform: rotatey(-180deg);
}
.flipcard .face {
padding: 1em;
text-align: center;
-webkit-backface-visibility: hidden;
}
.flipcard .front {
background: #220000;
color: white;
}
.flipcard .back {
background: #66eeff;
color: black;
-webkit-transform: rotateY(180deg);
}
JSFiddle: http://jsfiddle.net/luken/qdBEV/
As you can see, the content from the front is interfering with the back, and they both stretch the flipcard to the combined height. I'd like the front to show with the proper height of its content and the back to show with the proper height of its content. I've tried making the faces position: absolute and making them go from display: none to display: block on each flip... but nothing works quite right.
Any ideas?
Add proper display:none; and display:block;
Demo: http://jsfiddle.net/qdBEV/3/
CSS:
body {
background: #bbb;
}
.flipcard {
perspective: 800;
-moz-perspective: 800;
-webkit-perspective: 800;
margin: 1em auto;
width: 80%;
border: solid 1em white;
border-radius: 0.5em;
font-family: Georgia;
transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
transition: 0.5s;
-moz-transition: 0.5s;
-webkit-transition: 0.5s;
cursor: pointer;
}
.flipcard:hover {
box-shadow: 0 0 1em black;
}
.flipcard.flipped {
transform: rotatey(-180deg);
-moz-transform: rotatey(-180deg);
-webkit-transform: rotatey(-180deg);
}
.flipcard .face {
padding: 1em;
text-align: center;
backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.flipcard .front {
background: #220000;
color: white;
display: block; /* added to fix the problem */
}
.flipcard.flipped .front {
display:none; /* added to fix the problem */
}
.flipcard .back {
background: #66eeff;
color: black;
transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
display:none; /* added to fix the problem */
}
.flipcard.flipped .back {
display:block; /* added to fix the problem */
}
I had to implement this problem at work and maybe this post will help others, so here is what I came up with (see jsfiddle). First off, the requirements in my case were a bit tighter than a flipping div with different height faces. Additionally:
There is content below the flip card that has to shift up and down smoothly (e.g. another CSS transiton) while the card flips in order to accommodate for the different heights of the faces.
The content on the faces as well as what is above and below the flip card has to adhere to the responsive design of the page, in other words the card cannot have any fixed CSS dimensions nor absolute positioning.
Support for all major browsers, but only latest versions.
HTML is the same as in the question - one "card" with two "faces":
<div class="flipcard">
<div class="flipcard-front">
<h1>Front</h1>
<p>some shorter content</p>
</div>
<div class="flipcard-back">
<h1>Back</h1>
<p>some long content</p>
...
</div>
</div>
CSS (looks daunting, but actually just a couple of line of LESS):
.flipcard {
position: relative;
height: auto;
min-height: 0px;
/* Flip card styles: WebKit, FF, Opera */
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
-webkit-transition: min-height 1s ease-out 0s, -webkit-transform 1s ease-out 0.5s;
-moz-transition: min-height 1s ease-out 0s, -moz-transform 1s ease-out 0.5s;
-o-transition: min-height 1s ease-out 0s, -o-transform 1s ease-out 0.5s;
/* only height adjustment for IE here */
-ms-transition: min-height 1s ease-out 0s;
}
/* The class that flips the card: WebKit, FF, Opera */
.flipcard.card-flipped {
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
}
.flipcard .flipcard-front,
.flipcard .flipcard-back {
top: 0;
left: 0;
width: 100%;
/* backface: all browsers */
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
/* Flip card styles: IE 10,11 */
-ms-perspective: 800px;
-ms-transform-style: flat;
-ms-transition: -ms-transform 1s ease-out 0.5s;
}
.flipcard .flipcard-front {
position: relative;
display: inline-block;
-webkit-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
transform: rotateY(0deg);
}
.flipcard .flipcard-back {
position: absolute;
display: none;
-ms-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
transform: rotateY(180deg);
/* webkit bug: https://bugs.webkit.org/show_bug.cgi?id=54371,
You need this fix if you have any input tags on your back face */
-webkit-transform: rotateY(180deg) translateZ(1px);
}
/* The 2 classes that flip the faces instead of the card: IE 10,11 */
.flipcard .flipcard-front.ms-front-flipped {
-ms-transform: rotateY(180deg);
}
.flipcard .flipcard-back.ms-back-flipped {
-ms-transform: rotateY(0deg);
}
Notes: Unfortunately the latest versions of IE still handle CSS rotations differently than all the others in that it expects each face to be flipped individually instead of flipping the card that contains them. Although webKit browsers, FF and Opera seem to "understand" this, I wanted maximal backward compatibility for those browsers and hence all this ugly browser prefix clutter (google for David Walsh's great post on flip cards). Secondly, I wanted older browsers to at least show the right content and so the invisible (back) face had to be display: none while the visible face had to be display: block-inline to avoid collapsed margins with content above and below the card. Thirdly, the shifting of the content following the flip card can be achieved by controlling the cards min-height property while leaving it's height: auto (credit). Running the shift a bit ahead of the rotation makes it really smooth.
Finally, the Javascript:
function flipCard() {
var card = $('.flipcard');
var front = $('.flipcard-front');
var back = $('.flipcard-back');
var tallerHight = Math.max(front.height(), back.height()) + 'px';
// visible/invisible *before* the card is flipped ;D
var visible = front.hasClass('ms-front-flipped') ? back : front;
var invisible = front.hasClass('ms-front-flipped') ? front : back;
var hasTransitioned = false;
var onTransitionEnded = function () {
hasTransitioned = true;
card.css({
'min-height': '0px'
});
visible.css({
display: 'none',
});
// setting focus is important for keyboard users who might otherwise
// interact with the back of the card once it is flipped.
invisible.css({
position: 'relative',
display: 'inline-block',
}).find('button:first-child,a:first-child').focus();
}
// this is bootstrap support, but you can listen to the browser-specific
// events directly as well
card.one($.support.transition.end, onTransitionEnded);
// for browsers that do not support transitions, like IE9
setTimeout(function() {
if (!hasTransitioned) {
onTransitionEnded.apply();
}
}, 2000);
invisible.css({
position: 'absolute',
display: 'inline-block'
});
card.css('min-height', tallerHight);
// the IE way: flip each face of the card
front.toggleClass('ms-front-flipped');
back.toggleClass('ms-back-flipped');
// the webkit/FF way: flip the card
card.toggleClass('card-flipped');
}
This applies the classes for flipping the card/faces. During the transition, the back face has a position: absolute so it is visible while the card is turned. At the same time, the card's height is transitioned. At the end of the transition, the visible face returns to is position: relative and the card's height is derestricted leaving back a responsive page.
Hope this helps - sorry for this lengthy post, it's my first :)

CSS hover firing more than once with webkit 3d transform

When I use a webkit 3d transform on hover, only the top 50% of the hover area works, while the bottom 50% is unstable. I'm currently testing on Chrome (31.0.1650.63). Is it a bug? Is there any workaround?
Try to place your mouse on the top of the div and slowly bring it to the bottom.
HTML
<div class="hoverArea"></div>
<div class="flip">
<div class="front">front</div>
<div class="back">back</div>
</div>
CSS
.hoverArea, .flip, .front, .back {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.hoverArea {
z-index: 10;
}
.flip {
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
-webkit-perspective: 800;
z-index: 9;
}
.front {
background-color: #f00;
-webkit-backface-visibility: hidden ;
}
.back {
background-color: #f0f;
-webkit-transform: rotatex(-180deg);
-webkit-backface-visibility: hidden ;
}
.hoverArea:hover + .flip {
-webkit-transform: rotatex(-180deg);
}
http://jsfiddle.net/4P53y/
You can fix it by removing the .hoverArea element and instead apply the :hover event on the .flip element.
.flip:hover {
-webkit-transform: rotatex(-180deg);
}
Demo
If you want to still use the .hoverArea element then you can use transform:translateZ(1px); on .hoverArea to make it function correctly. It makes the browser render the element more carefully
.hoverArea {
z-index: 10;
-webkit-transform:translateZ(1px);
}
Demo

Resources