26

After looking through IE10's developer blog I have found that they do not support the preserve-3d setting.

They do offer a workaround, but I can not seem to get it working. My example below works in Safari, Chrome and Firefox but not IE10. If anyone could help me achieve this I would be very thankful.

The boxes should rotate around the Y axis on click to show some text and a green background color. This is not the case in IE10

My example: http://codepen.io/2ne/pen/zEpge

Part of code:

HTML

<div class="flip-wrapper">
    <div class="front"></div>
    <div class="back">IE10 SUCKS</div>
</div>

CSS

.flip-wrapper {
    cursor: pointer;
    height: 100%;
    -moz-perspective: 1000;
    -webkit-perspective: 1000;
    -ms-perspective: 1000;
    perspective: 1000;
    -moz-transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    -ms-transform-style: preserve-3d;
    transform-style: preserve-3d;
    width: 100%;
}

.flip-wrapper .front,
.flip-wrapper .back {
    -moz-backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    -ms-backface-visibility: hidden;
    backface-visibility: hidden;
    height: 100%;
    position: absolute;
    width: 100%;
}

.flip-wrapper .back {
  background: none repeat scroll 0 0 #298F68;
    -webkit-transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
    transform: rotateY(180deg);
}

.flip-wrapper.flipped {
  cursor: default;
  -webkit-animation: flip 500ms 1;
    -moz-animation: flip 500ms 1;
    animation: flip 500ms 1;
    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    -ms-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}

2ne

2ne
  • 5,766
  • 9
  • 30
  • 51
  • 2
    Just a note that IE for Win 10 Tech Preview now includes preserve-3d support: http://blogs.msdn.com/b/ie/archive/2014/11/11/living-on-the-edge-our-next-step-in-interoperability.aspx – David Storey Nov 13 '14 at 07:37

6 Answers6

21

I also couldn't seem to find a good example of this anywhere, so I spent some way too much time making my own.

This one works on all browsers, does not have that weird 360deg IE flip, and includes provision for static content (that lives on both sides of the card - which I needed to put a 'flip' button at the top right of both sides).

--I tested on latest versions of Chrome, Firefox, Safari, Opera, and IE.

http://jsfiddle.net/Tinclon/2ega7yLt/7/

Edit: Also works with transparent backgrounds: http://jsfiddle.net/Tinclon/2ega7yLt/8/

The css (of course) includes IE hacks, so it's a bit long, but the html is quite straightforward:

<div class="card">
  <div class="content">
    <div class="cardFront">FRONT CONTENT</div>
    <div class="cardBack">BACK CONTENT</div>
    <div class="cardStatic">STATIC CONTENT</div>
  </div>
</div>

$('.card').hover(function(){$('.card').toggleClass('applyflip');}.bind(this));

.card {
    perspective: 1000px;
    -webkit-perspective: 1000px;
    -moz-perspective: 1000px;
    -o-perspective: 1000px;
    -ms-perspective: 1000px;
    margin:80px 150px;
    width:320px;
    height:243px;
    vertical-align:top;
    position:absolute;
    display:block;
    font-size:25px;
    font-weight:bold;
}

.card .content {
    transition: 0.5s ease-out;
    -webkit-transition: 0.5s ease-out;
    -moz-transition: 0.5s ease-out;
    -o-transition: 0.5s ease-out;
    -ms-transition: 0.5s ease-out;
    transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    -o-transform-style: preserve-3d;
    -ms-transform-style: preserve-3d;

    /* content backface is visible so that static content still appears */
    backface-visibility: visible;
    -webkit-backface-visibility: visible;
    -moz-backface-visibility: visible;
    -o-backface-visibility: visible;
    -ms-backface-visibility: visible;


    border: 1px solid grey;
    border-radius: 15px;
    position:relative;
    width: 100%;
    height: 100%;

}
.card.applyflip .content {
    transform: rotateY(180deg);
    -webkit-transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
    -o-transform: rotateY(180deg);
    -ms-transform: rotateY(180deg);
}


.card .content .cardStatic {
    /* Half way through the card flip, rotate static content to 0 degrees */
    transition: 0s linear 0.17s;
    -webkit-transition: 0s linear 0.17s;
    -moz-transition: 0s linear 0.17s;
    -o-transition: 0s linear 0.17s;
    -ms-transition: 0s linear 0.17s;
    transform: rotateY(0deg);
    -webkit-transform: rotateY(0deg);
    -moz-transform: rotateY(0deg);
    -o-transform: rotateY(0deg);
    -ms-transform: rotateY(0deg);

    text-align: center;
    position: absolute;
    top: 0;
    left: 0;
    height: 0;
    width: 100%;
    line-height:100px;
}

.card.applyflip .content .cardStatic {
    /* Half way through the card flip, rotate static content to -180 degrees -- to negate the flip and unmirror the static content */
    transition: 0s linear 0.17s;
    -webkit-transition: 0s linear 0.17s;
    -moz-transition: 0s linear 0.17s;
    -o-transition: 0s linear 0.17s;
    -ms-transition: 0s linear 0.17s;
    transform: rotateY(-180deg);
    -webkit-transform: rotateY(-180deg);
    -moz-transform: rotateY(-180deg);
    -o-transform: rotateY(-180deg);
    -ms-transform: rotateY(-180deg);
}

.card .content .cardFront {
    background-color: skyblue;
    color: tomato;
}

.card .content .cardBack {
    background-color: tomato;
    color: skyblue;
}

.card .content .cardFront, .card .content .cardBack {
    /* Backface visibility works great for all but IE. As such, we mark the backface visible in IE and manage visibility ourselves */
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -o-backface-visibility: hidden;
    -ms-backface-visibility: visible;
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    text-align: center;
    line-height:200px;
    border-radius: 14px;
}
.card .content .cardFront, .card.applyflip .content .cardFront {
    transform: rotateY(0deg);
    -webkit-transform: rotateY(0deg);
    -moz-transform: rotateY(0deg);
    -o-transform: rotateY(0deg);
    -ms-transform: rotateY(0deg);
}

.card .content .cardBack, .card.applyflip .content .cardBack {
    transform: rotateY(-180deg);
    -webkit-transform: rotateY(-180deg);
    -moz-transform: rotateY(-180deg);
    -o-transform: rotateY(-180deg);
    -ms-transform: rotateY(-180deg);
}

.card .content .cardFront, .card.applyflip .content .cardBack {
    /* IE Hack. Halfway through the card flip, set visibility. Keep other browsers visible throughout the card flip. */
    animation: stayvisible 0.5s both;
    -webkit-animation: stayvisible 0.5s both;
    -moz-animation: stayvisible 0.5s both;
    -o-animation: stayvisible 0.5s both;
    -ms-animation: donothing 0.5s;
    -ms-transition: visibility 0s linear 0.17s;
    visibility: visible;
}
.card.applyflip .content .cardFront, .card .content .cardBack {
    /* IE Hack. Halfway through the card flip, set visibility. Keep other browsers visible throughout the card flip. */
    animation: stayvisible 0.5s both;
    -webkit-animation: stayvisible 0.5s both;
    -moz-animation: stayvisible 0.5s both;
    -o-animation: stayvisible 0.5s both;
    -ms-animation: donothing 0.5s;
    -ms-transition: visibility 0s linear 0.17s;
    visibility: hidden;
}
@keyframes stayvisible { from { visibility: visible; } to { visibility: visible; } }
@-webkit-keyframes stayvisible { from { visibility: visible; } to { visibility: visible; } }
@-moz-keyframes stayvisible { from { visibility: visible; } to { visibility: visible; } }
@-o-keyframes stayvisible { from { visibility: visible; } to { visibility: visible; } }
@-ms-keyframes donothing { 0% { } 100% { } }
Tinclon
  • 967
  • 11
  • 18
  • very nice ! - im trying to port an infinite flip animation. meaning it keeps running. work fine in ff/chrome with `animation: 3s coinFlip ...` but IE just shows the backface in reverse... i would need to somehow mix these two things together.. do you have an idea? – Adeerlike Mar 20 '15 at 16:05
  • Give this a try: http://jsfiddle.net/Tinclon/2ega7yLt/72/ Interestingly, the "STATIC" part flickers a tiny bit in Chrome, but seems to work better in all the other browsers. – Tinclon Mar 25 '15 at 16:07
  • This is a great answer, but it would be even better if you could explain exactly where the "hack" is. – Chuck Le Butt Nov 11 '15 at 12:09
  • The "hack" is explained in the code in the comments: /* IE Hack. Halfway through the card flip, set visibility. Keep other browsers visible throughout the card flip. */ – Tinclon Nov 12 '15 at 15:04
  • Late to the thread, but your code just helped me out a ton! Thank you! – Rebecca O'Riordan Nov 14 '17 at 15:07
4

Here is a far simpler flip algorithm, which will also work in IE. https://jsfiddle.net/mff4jzd2/8/

JAVASCRIPT:

        var state = 0;

        $('.container').on('click',function(){
            if(state == 0){

                state = 1;
                $('.front').addClass('flip-front');
                $('.back').addClass('flip-back');

            }
            else{

                state = 0;
                $('.front').removeClass('flip-front');
                $('.back').removeClass('flip-back');

            }   
        });

CSS:

    .container{

        width:170px;
        height:280px;
        display:inline-block;
        position:relative;
        transform: perspective(400px);
        cursor:pointer;

    }
    .front{

        position:absolute;
        top:0;
        left:0;
        width:100%;
        height:100%;
        background-color:blue;        
        transform: perspective(400px) rotateY(0deg);        
        backface-visibility: hidden;
        transition: 1.0s;
        opacity:1;
        box-shadow: 0 8px 6px -6px black;
    }
    .back{

        position:absolute;
        top:0;
        left:0;
        width:100%;
        height:100%;
        background-color:green;       
        transform: perspective(400px) rotateY(-180deg);         
        backface-visibility: hidden;
        transition: 1.0s;
        opacity:0;
        box-shadow: 0 8px 6px -6px black;
    }       
    .flip-front{
        opacity:0;
        transform: perspective(400px) rotateY(180deg);

    }
    .flip-back{
         opacity:1;  
         transform: perspective(400px) rotateY(0deg);
    }   

HTML:

<div class="container">

    <div class="back"></div>
    <div class="front"></div>

</div>
MarzSocks
  • 4,229
  • 3
  • 22
  • 35
2

Found the answer here. Posted my own updated fiddle here - this is the css (I included ms prefixes only for brevity):

.container {
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
border: 1px solid #CCC;
-ms-perspective: 1000;
perspective: 1000;
}

.card {
display: block;
height: 100%;
width: 100%;
line-height: 260px;
color: white;
text-align: center;
font-weight: bold;
font-size: 140px;
position: absolute;
transition: all 0.5s linear;
backface-visibility: hidden;
}

.card.flipped {
    -ms-transform: rotateY(360deg);
    transform: rotateY(360deg);
}

.front {
    background: red;
}
.back {
    background: #00f;
    transform: rotateY( 180deg );
}

.container:hover .card {
    -ms-transform: rotateY(360deg);
    transform: rotateY(360deg);
}

Here is a button handler for flipping (in addition to the hover event):

$('button').click(function() {
    $('.card').toggleClass('flipped');
});

Interesting (and somewhat troubling) that the answer for IE10 is flipping by 360 degrees (the 'flipped' class and hover event in the css). Still wrapping my head around that one.

Here's hoping they implement preserve-3d soon.

Community
  • 1
  • 1
ericb
  • 113
  • 1
  • 7
2

here is a very simple version of Nicholls

flipping rectangle

#container {
 position: relative;
 height:362px;
 width: 282px;
 margin: 0 auto;
}

#container div {
 position:absolute;
 left:0;
 top:0;
 width:242px;
 height: 322px;
 padding:20px;
 background:#463;
 -ms-border-radius: 5px;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;
 border-radius: 5px;
 -webkit-transition: 1.5s ease-in-out;
 -moz-transition: 1.5s ease-in-out;
 -ms-transition: 1.5s ease-in-out;
 -o-transition: 1.5s ease-in-out;
 transition: 1.5s ease-in-out;
}

#container:hover div.upper {
 -webkit-transform: perspective(800px) rotateY(179.9deg);
 -moz-transform: perspective(800px) rotateY(179.9deg);
 transform: perspective(800px) rotateY(179.9deg);
}

<div id="container" aria-haspopup="true">    
   <div class="upper"></div>
</div>

I left only the flip code.

Btw, great effects Nicholls !

Kulerbox
  • 200
  • 2
  • 12
klugout
  • 21
  • 2
2

Use a browser-determiner JS or any other method to apply CSS-styles to IE only.

Then use the following code:

.ie .flip-wrapper:hover .back {
    -ms-backface-visibility: visible;
}

.ie .flip-wrapper:hover .front {
    visibility: hidden;
}
1

As the OP notes, there is an answer to the question on their blog, but sadly he did not quote:

Note The W3C specification defines a keyword value of preserve-3d for this property, which indicates that flattening is not performed. At this time, Internet Explorer 10 does not support the preserve-3d keyword. You can work around this by manually applying the parent element's transform to each of the child elements in addition to the child element's normal transform.

In summary, as normal, Microsoft's Browser is badly broken.

On further investigation, it seems that the interpolation engine is incomplete or broken in IE10; applying everything in terms of matrix transforms causes 'random' flips to occur when rotation about more than one axis is involved. The only method of matrix interpolation would be to manually handle all interpolation manually. Further, it seems that any interpolation where a right angle is involved will cause inconsistent 'random' flipping.

I have succeeded in interpolating the required css, however (minified), the code is thousands of lines long. So, yeah, IE can do 3d css, if you don't mind pre-compiling and long wait-times.

smaudet
  • 609
  • 8
  • 17