DEV Community

Skymax
Skymax

Posted on

backface-visibility doesn't work when used together with an animation

I'm trying to make a card flip effect with CSS keyframes but for some reason the transform: rotateY() doesn't rotate correctly. When it's rotated by the @keyframes, after it passes rotateY(90deg) the front side isn't shown, instead it shows the flipped back side. When flipping the card "manually" (in the inspect element), it works fine.

The card by default is showing the front side. But the animation starts with the back side and then it flips. The animation is keeping its ending state.

As far as I could see, for some reason, the front side is always behind the back side. (If you opacity the back side, the front side can be seen.)

I've tried:

  • Adding perspective: 1000px; to the parent element (.cards).
  • Using positive rotateY() instead of negative.
  • Adding z-index to .front.
  • Adding transform: rotateY(0deg); to .front, so it knows that that's the front side.
  • Adding backface-visibility: hidden; to both, .front and .back.
  • Adding positon: relative; on one (and both), .front and .back.

But none of these fixed it.

Here you can see a video of the issue:

When @keyframes does it:
https://gyazo.com/7cd4e75c85ed5eba6b1e717a37ce95c2

When I manually do it (with the Inspect Element):
https://gyazo.com/42e63ff2e4fe0149b917e895a633dd88

Here's the code:

HTML:
<div class="cards">
    <div class="card">
        <div class="front">
            <div class="card-number">5</div>
            <img src="https://bounty-assets.fra1.cdn.digitaloceanspaces.com/cards/clubs.png" alt="">
        </div>
        <div class="back">
            <img src="https://bounty-assets.fra1.cdn.digitaloceanspaces.com/cards/back.png" alt="">
        </div>
    </div>
</div>
CSS:
.cards {
    width: fit-content;
    display: flex;
    position: absolute;
    top: 25px;
    left: 0;
    right: 0;
    margin: 0 auto;
    perspective: 1000px;
}

.cards .card {
    min-width: auto;
    width: 208px;
    background: transparent;
    border: 0;
    border-radius: 0;
    display: flex;
    position: relative;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    margin-left: -30px;
    transform: rotateY(0deg);
    animation: flipcard 1s linear 0s 1 forwards;
}

.cards .card:first-child {
    margin-left: 0;
}

.cards .card .front {
    position: absolute;
    backface-visibility: hidden;
    transform: rotateY(0deg);
}

.cards .card .front .card-number {
    position: absolute;
    top: 30px;
    left: 35px;
    font-size: 32px;
    font-weight: 600;
}

.cards .card .back {
    position: absolute;
    transform: rotateY(180deg);
}

@keyframes flipcard {
    0% {
        opacity: 0;
        transform: translate(30vw, 30vh) rotateY(-180deg);
    }
    30% {
        opacity: 1;
        transform: translate(0, 0) rotateY(-180deg);
    }
    50% {
        opacity: 1;
        transform: translate(0, 0) rotateY(-180deg);
    }
    60% {
        transform: translate(-20px, 0) rotateY(-180deg);
    }
    80% {
        transform: translate(-30px, 0) rotateY(-90deg) scale(1.08);
    }
    90% {
        transform: translate(0, 0) rotateY(0deg) scale(1.08);
    }
    100% {
        transform: translate(0, 0) rotateY(0deg) scale(1);
    }
}

Top comments (4)

Collapse
 
skymax profile image
Skymax

I fixed it. Belive it or not, the opacity in the keyframes was causing this issue.

Collapse
 
brandonmcconnell profile image
Brandon McConnell

@skymax you are a saint. I've been troubleshooting this issue for hours today before finding your fix. I removed my opacity from my transition, and everything started working as expected.

Collapse
 
ngustavo profile image
Gustavo Nascimento

Same. It took me 6 hours. Then, I found this article. It should be shared more.

Collapse
 
dave470003 profile image
David

Thanks for this, I needed it