CSS3 Flip Card with Automatic Height

10,455

Solution 1

Here's a working solution on jsFiddle.

JS:

$('.flip').click(function(){
    $(this).find('.card').addClass('flipped');
    return false;
}).mouseleave(function () {
    $('.flip > .card').removeClass('flipped');
});

var frontHeight = $('.front').outerHeight();
var backHeight = $('.back').outerHeight();

if (frontHeight > backHeight) {
    $('.flip, .back').height(frontHeight);
}
else if (frontHeight > backHeight) {
    $('.flip, .front').height(backHeight);
}
else {
    $('.flip').height(backHeight);
}

A defined height isn't flexible, so what you're seeing is what you've defined. Since the height will not remain constant, the front or the back needs to have a defined height that matches whichever element is the tallest. In the example, .front is taller, so .back is updated to have the same height, allowing you to achieve the vertical flip effect at the center.

In your example, the mouseleave event can fire while the elements during the animation. I have assumed that you did not want this to occur, so I've updated the logic to remove .flipped when leaving the card, which retains its height throughout the animation. I also cleaned up the CSS to be less redundant. Hope this helps!

Solution 2

You can trick it, by making the .back position absolute and 100% height. And leave the .front position relative.

.front  {position: relative;}
.back       {position: absolute; top: 0; left: 0; width: 100%; height: 100%;}

Note, might be useful in some scenarios: add 2 additional elements to the back, for header and footer, and make the footer position absolute and set it to bottom 0.

Share:
10,455
Jon
Author by

Jon

Programmer. Designer. Photo-/Videographer. Musician.

Updated on June 11, 2022

Comments

  • Jon
    Jon almost 2 years

    I'm using a tutorial to create a flip card effect using CSS3 and jQuery and I'm having issues getting the height to adjust to the content length while having it still flip on the center horizontal.

    FIDDLE.

    Code:

    <div class="flip"> 
        <div class="card"> 
            <div class="face front"> 
                Front<br> Other text.<br> Other text.<br> Other text.<br> Other text.
            </div> 
    
            <div class="face back"> 
                Back
            </div> 
        </div> 
    </div> 
    

    body {
     background: #ccc;   
    }
    .flip {
      -webkit-perspective: 800;
       width: 400px;
       height: 200px;
        position: relative;
        margin: 50px auto;
    }
    .flip .card.flipped {
      -webkit-transform: rotatex(-180deg);
    }
    .flip .card {
      width: 100%;
      height: 100%;
      -webkit-transform-style: preserve-3d;
      -webkit-transition: 0.5s;
    }
    .flip .card .face {
      width: 100%;
      height: 100%;
      position: absolute;
      -webkit-backface-visibility: hidden ;
      z-index: 2;
        font-family: Georgia;
        font-size: 3em;
        text-align: center;
    }
    .flip .card .front {
      position: absolute;
      z-index: 1;
        background: black;
        color: white;
        cursor: pointer;
    }
    .flip .card .back {
      -webkit-transform: rotatex(-180deg);
        background: blue;
        background: white;
        color: black;
        cursor: pointer;
    }​
    

    $('.flip').click(function(){
        $(this).find('.card').addClass('flipped').mouseleave(function(){
            $(this).removeClass('flipped');
        });
        return false;
    });​
    

  • Jon
    Jon over 11 years
    This is great! Thank you so much. One question though. I seem to be getting a different animation when there is just one line of text. Granted this will probably never be an issue where I'm using it, is there a way to fix this so that the behavior is the same as with multiple lines?
  • Logda
    Logda over 11 years
    I hadn't even tried it with one line, but I'll see what I can come up with.
  • Jon
    Jon over 11 years
    As I said, it's unlikely to occur, but I just wasn't sure why it was different.
  • Logda
    Logda over 11 years
    I've updated the example url. The .flip container needs a defined height as well, and when the heights are the same, only that element should be updated.
  • Jon
    Jon over 11 years
    Perfect! Great work. I've been toying with the height attributes for an hour trying to figure it out. I knew the fixed height definition was a problem, but I couldn't figure out how to fix it. Many many thanks!
  • Brian McCutchon
    Brian McCutchon almost 11 years
    Doesn't work in FF 21.0 for Mac. It just shows the back and won't flip.
  • Logda
    Logda almost 11 years
    @Sortofabeginner The -moz prefix is needed on some of the CSS3 properties. I haven't spent the time to determine which, so here's the above fiddle updated with -moz prefixed properties: fiddle
  • Philip Downer
    Philip Downer about 7 years
    Nice little hack for this particular use!
  • Brian M. Hunt
    Brian M. Hunt about 7 years
    What if the back is larger than the front?
  • Fabien Snauwaert
    Fabien Snauwaert about 5 years
    If the back is consistently going to be larger than the front, then you can just swap the attributes given above (i.e.: simply .back {position: relative;} .front {position: absolute; top: 0; left: 0; width: 100%; height: 100%;}) If you do not know which one is going to be bigger then it seems we're down to testing with JavaScript (can add a wrapper to the content of each face and measure that.)