← Back to all tutorials

Flipping Cards Animation

Create 3D flipping cards with front and back faces that flip on hover — using CSS 3D transforms and backface-visibility.

Flipping Cards Animation

Let's build 3D flipping cards that reveal a back face on hover — a popular UI pattern for team profiles, product features, and pricing cards. This uses perspective, rotateY, and backface-visibility.

The HTML Structure

<div class="card-grid">
    <div class="flip-card">
        <div class="flip-card-inner">
            <div class="flip-card-front">
                <div class="card-emoji">👨‍💻</div>
                <h3>John Doe</h3>
                <p>Front-End Developer</p>
            </div>
            <div class="flip-card-back">
                <h3>About John</h3>
                <p>Passionate about CSS animations, 
                   React, and building beautiful UIs.</p>
                <a href="#" class="card-link">View Profile →</a>
            </div>
        </div>
    </div>

    <div class="flip-card">
        <div class="flip-card-inner">
            <div class="flip-card-front">
                <div class="card-emoji">👩‍🎨</div>
                <h3>Jane Smith</h3>
                <p>UI/UX Designer</p>
            </div>
            <div class="flip-card-back">
                <h3>About Jane</h3>
                <p>Designs intuitive interfaces with a focus 
                   on accessibility and micro-interactions.</p>
                <a href="#" class="card-link">View Profile →</a>
            </div>
        </div>
    </div>

    <div class="flip-card">
        <div class="flip-card-inner">
            <div class="flip-card-front">
                <div class="card-emoji">👨‍🔧</div>
                <h3>Mike Chen</h3>
                <p>Back-End Engineer</p>
            </div>
            <div class="flip-card-back">
                <h3>About Mike</h3>
                <p>Builds scalable APIs and loves optimizing 
                   database queries for performance.</p>
                <a href="#" class="card-link">View Profile →</a>
            </div>
        </div>
    </div>
</div>

How 3D Card Flip Works

The card has three nested layers:

  1. .flip-card — the outer container that defines the 3D perspective
  2. .flip-card-inner — rotates on hover (this is what actually flips)
  3. .flip-card-front and .flip-card-back — two faces stacked on top of each other

The Outer Container

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 30px;
    padding: 40px;
    max-width: 900px;
    margin: 0 auto;
}

.flip-card {
    height: 320px;
    perspective: 1000px;  /* Creates the 3D space */
}

perspective on the parent creates a 3D rendering context. Lower values = more dramatic 3D effect. 1000px gives a natural-looking depth.

The Inner Container (The Flipper)

.flip-card-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
    transform-style: preserve-3d;  /* Allow children to be 3D */
}

.flip-card:hover .flip-card-inner {
    transform: rotateY(180deg);
}

transform-style: preserve-3d is crucial — without it, the children are flattened into 2D and the flip shows nothing.

The Front and Back Faces

.flip-card-front,
.flip-card-back {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 30px;
    backface-visibility: hidden;  /* Hide the back when facing away */
}

.flip-card-front {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

.flip-card-back {
    background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
    color: white;
    transform: rotateY(180deg);  /* Pre-rotated — hidden initially */
}

The Key Property: backface-visibility

ValueEffect
visible (default)The back of the element is visible (mirrored)
hiddenThe back is invisible — only shows when facing the viewer

Both faces have backface-visibility: hidden. The back face is pre-rotated 180°. When the inner container rotates 180°, the front face rotates away (hidden) and the back face rotates to face the viewer (visible).

Styling Card Content

.card-emoji {
    font-size: 64px;
    margin-bottom: 16px;
}

.flip-card-front h3 {
    font-size: 22px;
    margin-bottom: 6px;
}

.flip-card-front p {
    font-size: 14px;
    opacity: 0.85;
}

.flip-card-back h3 {
    font-size: 20px;
    margin-bottom: 12px;
}

.flip-card-back p {
    font-size: 14px;
    line-height: 1.7;
    opacity: 0.9;
    margin-bottom: 20px;
    text-align: center;
}

.card-link {
    color: #fff;
    font-weight: 600;
    padding: 10px 20px;
    border: 2px solid rgba(255,255,255,0.5);
    border-radius: 8px;
    text-decoration: none;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.card-link:hover {
    background: rgba(255,255,255,0.15);
    border-color: #fff;
}

Horizontal vs Vertical Flip

/* Horizontal flip (default — rotates around Y axis) */
.flip-card:hover .flip-card-inner {
    transform: rotateY(180deg);
}
.flip-card-back {
    transform: rotateY(180deg);
}

/* Vertical flip (rotates around X axis) */
.flip-card:hover .flip-card-inner {
    transform: rotateX(180deg);
}
.flip-card-back {
    transform: rotateX(180deg);
}

3D Properties Summary

PropertyApplied ToPurpose
perspectiveParent containerCreates 3D depth
transform-style: preserve-3dThe rotating elementPreserves 3D for children
backface-visibility: hiddenBoth facesHides the element when rotated away
transform: rotateY(180deg)Back face (initial), inner on hoverPerforms the flip

Key Takeaways

  • 3D card flips need three layers: container (perspective), flipper (rotates), and two faces
  • perspective on the outer container creates the 3D space
  • transform-style: preserve-3d is required for children to participate in 3D
  • backface-visibility: hidden hides each face when it's rotated away from the viewer
  • The back face is pre-rotated 180° — the flip reveals it naturally
  • Use rotateY for horizontal flips and rotateX for vertical flips