2

I'm trying to create a simple reusable CSS class so I can have this animation everywhere.

Everything works fine except that I can't find any example/documentation on how to trigger the reverse animation.

Here is my HTML:

<div class="cards">
        <div class="card">
            <div class="frontpage">
                <img src="http://lorempixel.com/400/200/"/>
            </div>
            <div class="rearpage">
                <img src="http://lorempixel.com/g/400/200/"/>
            </div>
        </div>

        <div class="card">
            <div class="frontpage">
                <img src="http://lorempixel.com/400/200/"/>
            </div>
            <div class="rearpage">
                <img src="http://lorempixel.com/g/400/200/"/>
            </div>
        </div>
</div>

My animation is a "card-flip"-like animation using a simple toggleClass in Javascript to trigger the animation:

$('.card').click(function(){
    $(this).toggleClass('opened');
});

And here is my CSS:

.cards {
    width: 800px;
    margin: auto;
}

.card {
    width: 200px;
    height: 100px;
    position: relative;
    display: inline-block;
    margin: 10px;
}

.card .frontpage, .card .rearpage {
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: absolute;
}


.card .rearpage {
    width: 0%;
}

.card .frontpage img, .card .rearpage img {
    width: 100%;
    height: 100%;
}


/***** ANIMATIONS *****/

/* ANIMATION 1 */
.card .frontpage {
    -webkit-animation-duration: 1s;
    -webkit-animation-direction: alternate;
    -webkit-animation-timing-function: ease-in;
    -webkit-animation-fill-mode: forwards;
}

.card.opened .frontpage {
    -webkit-animation-name: frontToRear;
}

@-webkit-keyframes frontToRear {
    0% { width: 100%; }
    50% { width: 0%; margin-left: 50%; }
    100% { width: 0%; }
}

/* ANIMATION 2 */
.card .rearpage {
    -webkit-animation-duration: 1s;
    -webkit-animation-direction: alternate;
    -webkit-animation-timing-function: ease-in;
    -webkit-animation-fill-mode: forwards;
}

.card.opened .rearpage {
    -webkit-animation-name: rearToFront;
}

@-webkit-keyframes rearToFront {
    0% { width: 0%; }
    50% { width: 0%; margin-left: 50%; }
    100% { width: 100%; }
}

What is the smart way of doing this? I wish I could just put some trigger on my .rearcard to trigger the reversed animation but I can't find any way of doing this.

I know I could just write 2 other "reversed" animations and apply them but it seems so dumb that I can't try to do better.

I set up a jsfiddle to help you analyze and test out: http://jsfiddle.net/9yp3U/

MaximeBernard
  • 1,090
  • 1
  • 19
  • 33

1 Answers1

4

Your approach with margin and width to fake a rotation is very interesting, but you can do this much more simply with rotateY

.cards {
    width: 800px;
    margin:auto;
    -webkit-perspective:1000;
}    
.card {
    width: 200px;
    height: 100px;
    position: relative;
    display: inline-block;
    margin: 10px;
    -webkit-transition: 1s ease-in;
    -webkit-transform-style: preserve-3d;
    -webkit-transform:translateZ(1px);
}    
.card .frontpage, .card .rearpage, img {
    width: 100%;
    height: 100%;
    position: absolute;
    top:0; 
    left:0;
    -webkit-transform-style: preserve-3d;
    -webkit-backface-visibility: hidden;
}
.card img {
    width: 100%;
    height: 100%;
}    
.card .rearpage,
.card.opened {
    -webkit-transform:rotateY(180deg);
}

Demo

As for the question you asked, you can play animations backwards by using the animation-direction:backwards property, though with CSS toggling animations is hard. Thus, I'd recommend you use a transition instead since it's only a change between two states.

And FYI just in case, CSS selector don't always have to be in the parent child format. In your case applying just .child will do the same. The parent child selector is only necessary when needing to a higher selector specificity than existing properties.

Oh, and also FYI, jQuery isn't needed for this. I included an (untested) javascript equivalent if you want. If this is the only place where you're using jQuery on your page I'd recommend not using it because loading the whole jQuery library takes some time and data.

Community
  • 1
  • 1
Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
  • 1
    Thanks for the tips. I read few days ago about the "translate" method to animate which is indeed much simpler. 1. But is one of these methods better for performance on mobile? I can see that "preserve-3d" and "backface-visibility: hidden" properties are used to display the rearpage. 2. But I don't get what the "translateZ(1px)" is used for? 3. The ".card.opened" selector makes it obvious that animation is set on the .card div. But if you do the animation on ".card .rearpage", the animation will be set on the div.rearpage right? Not on his parent (div.card)? – MaximeBernard Jul 04 '14 at 07:12
  • 1. Performance wise `transform` will perform better because it only affects the how the element is *visualized*, not the actual element. 2. The `translateZ(1px)` is used to force rendering by the GPU, for more about that [check here](http://dev.opera.com/articles/css-will-change-property/?utm_source=rss&utm_medium=rss&utm_campaign=everything-you-need-to-know-about-the-css-will-change-property). 3. You are correct. By using the comma, you can apply the same properties to multiple elements. By placing it on `.rearpage`, you set it to initialize on the back size.... – Zach Saucier Jul 04 '14 at 17:15
  • ... By setting it on `.opened`, you allow the whole card to be rotated when it is toggled – Zach Saucier Jul 04 '14 at 17:16