A Simple Card Swap Animation

What's it about?

A simple card swap animation using only HTML and CSS. Use it to show comparisons between two items.

2 min to read
css
html
beginner
learning

Final Output πŸŽ‰

Simple Card Swap Animation using HTML and CSS

HTML for the Cards πŸ’»

I know this looks scary πŸ˜†, but … seriously that’s about it πŸ˜…. Just two divs for the two cards.
What you wrap around these divs is up to you. You can use a section or a div whatever you like.

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

CSS for the Animation πŸ’»

Here’s how this animation works:

  • We position the two cards at their respective starting positions using the top and left properties.
  • We use @keyframes to define the animation for each card. i.e., how the card should move and when.
  • We use z-index to control which card is on top at any given time.

And that’s it! Simple right? 😊

The root variables are the fun part about this animation πŸ₯³
You can customize everything about the animation using these variables, (except for the 50% timeframe of the animation 😭) and the changes will be reflected in the animation.

I know this looks like a lot of code, but it’s really just the same thing repeated a few times πŸ˜›. So don’t be scared and just go through it once.

CSS
:root { --front-card-z-index: 1; --back-card-z-index: 0; --animation-duration: 6s; --card-width: 500px; --front-card-start-top: 0%; --front-card-start-left: 0%; --back-card-start-top: -10%; --back-card-start-left: 10%; } .front-card { position: absolute; z-index: var(--front-card-z-index); top: var(--front-card-start-top); left: var(--front-card-start-left); animation: swap-front-card var(--animation-duration) ease-in-out infinite alternate; } .back-card { position: absolute; z-index: var(--back-card-z-index); top: var(--back-card-start-top); left: var(--back-card-start-left); animation: swap-back-card var(--animation-duration) ease-in-out infinite alternate; } @keyframes swap-front-card { 0% { z-index: var(--front-card-z-index); top: var(--front-card-start-top); left: var(--front-card-start-left); } 25% { z-index: var(--front-card-z-index); top: var(--front-card-start-top); left: var(--front-card-start-left); } 40% { z-index: var(--front-card-z-index); top: var(--front-card-start-top); left: var(--front-card-start-left); } 49% { z-index: var(--front-card-z-index); } 50% { z-index: var(--back-card-z-index); top: calc(var(--front-card-start-top) - 10%); left: calc(var(--front-card-start-left) + 67%); } 75% { z-index: var(--back-card-z-index); top: var(--back-card-start-top); left: var(--back-card-start-left); } 100% { z-index: var(--back-card-z-index); top: var(--back-card-start-top); left: var(--back-card-start-left); } } @keyframes swap-back-card { 0% { z-index: var(--back-card-z-index); top: var(--back-card-start-top); left: var(--back-card-start-left); } 25% { z-index: var(--back-card-z-index); top: var(--back-card-start-top); left: var(--back-card-start-left); } 40% { z-index: var(--back-card-z-index); top: var(--back-card-start-top); left: var(--back-card-start-left); } 49% { z-index: var(--back-card-z-index); } 50% { z-index: var(--front-card-z-index); top: calc(var(--back-card-start-top) + 10%); left: calc(var(--back-card-start-left) - 20%); } 70% { z-index: var(--front-card-z-index); top: var(--front-card-start-top); left: var(--front-card-start-left); } 100% { z-index: var(--front-card-z-index); top: var(--front-card-start-top); left: var(--front-card-start-left); } }

That’s it!, thanks πŸ€— for reading all the way till down here