Search code examples
cssoverlapperspective

CSS - Incorrect overlpapping - 3D Perspective


I'm experimenting with CSS perspective to flip cards with a 3D effect, however when the right-most cards flip they are incorrectly overlapping. I have attempted to use Z-Index (which I am aware requires a positioning of anything but "static") however this has had no effect. Any help would be greatful. The project is in the following CodePen:

https://codepen.io/mikrayall/pen/WNzBxEw

HTML:

<div class="card">
        <div id="cardContents" class="cardContents1">
            <div class="cardFront"><h2>A</h2></div>
            <div class="cardBack"><p>Once there was a dog...</p></div>
        </div>
    </div>

    <div class="card">
        <div id="cardContents" class="cardContents2">
            <div class="cardFront"><h2>STORY</h2></div>
            <div class="cardBack"><p>A dog and a frog...</p></div>
        </div>
    </div>

    <div class="card">
        <div id="cardContents" class="cardContents3">
            <div class="cardFront"><h2>ABOUT</h2></div>
            <div class="cardBack"><p>The frog sat on the dog...</p></div>
        </div>
    </div>

    <div class="card">
        <div id="cardContents" class="cardContents2">
            <div class="cardFront"><h2>A</h2></div>
            <div class="cardBack"><p>Like the dog was a log...</p></div>
        </div>
    </div>

    <div class="card">
        <div id="cardContents" class="cardContents1">
            <div class="cardFront"><h2>DOG</h2></div>
            <div class="cardBack"><p>The dog ate the frog...!</p></div>
        </div>
    </div>

CSS:

*, *::before, *::after{
    margin: 0;
    box-sizing: border-box;
}

body{
    height:100vh;
    display:flex;
    justify-content:center;
    align-items: center;
    font-family: 'calibri';
    perspective:700px;
    background-image: linear-gradient(180deg, #000, #666)
}

.card{
    margin: auto 10px;
    width:6em;    
    border: 1px solid white;
    border-radius:0.3em;
    perspective: 700px;
    transform: rotateX(45deg);
    transform-style: preserve-3d;
    transform-origin:bottom;
}

#cardContents{
    position: relative;
    width: 6em;
    height: 8em;
    border-radius:0.3em;
    text-align: center;
    transition: transform 0.5s;
    transform-style: preserve-3d;
    transform-origin:bottom;
}

.cardFront, .cardBack{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    border-radius: 0.3em;
    backface-visibility: hidden;
    transform-style: preserve-3d;
    display:grid;
    align-content: center;
}

.cardFront{
    background-color: pink;
    border:0.2em solid white;
}

.cardBack{
    transform: rotateY(180deg);
    background: lightblue;
    border:0.2em solid white;
}

.card:hover #cardContents{
    transform: rotateX(-37deg) translateZ(100px) rotateY(180deg) translateY(-40px);
}

I've attempted to apply Z-Index to the various elements (.cardBack, .cardFront, .cardContents).

Any help gatefully appreciated. Thank you.


Solution

  • add z-index to the hovered card only

    .card:hover {
      z-index:1;
    }
    

    Full code

    *, *::before, *::after{
        margin: 0;
        box-sizing: border-box;
    }
    
    body{
        height:100vh;
        display:flex;
        justify-content:center;
        align-items: center;
        font-family: 'calibri';
        perspective:700px;
        background-image: linear-gradient(180deg, #000, #666)
    }
    
    .card{
        margin: auto 10px;
        width:6em;    
        border: 1px solid white;
        border-radius:0.3em;
        perspective: 700px;
        transform: rotateX(45deg);
        transform-style: preserve-3d;
        transform-origin:bottom;
    }
    
    #cardContents{
        position: relative;
        width: 6em;
        height: 8em;
        border-radius:0.3em;
        text-align: center;
        transition: transform 0.5s;
        transform-style: preserve-3d;
        transform-origin:bottom;
    }
    
    .cardFront, .cardBack{
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        border-radius: 0.3em;
        backface-visibility: hidden;
        transform-style: preserve-3d;
        display:grid;
        align-content: center;
    }
    
    .cardFront{
        background-color: pink;
        border:0.2em solid white;
    }
    
    .cardBack{
        transform: rotateY(180deg);
        background: lightblue;
        border:0.2em solid white;
    }
    .card:hover {
      z-index:1;
    }
    .card:hover #cardContents{
        transform: rotateX(-37deg) translateZ(100px) rotateY(180deg) translateY(-40px);
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="css.css">
        <title>Document</title>
    </head>
    <body>
        <div class="card">
            <div id="cardContents" class="cardContents1">
                <div class="cardFront"><h2>A</h2></div>
                <div class="cardBack"><p>Once there was a dog...</p></div>
            </div>
        </div>
    
        <div class="card">
            <div id="cardContents" class="cardContents2">
                <div class="cardFront"><h2>STORY</h2></div>
                <div class="cardBack"><p>A dog and a frog...</p></div>
            </div>
        </div>
    
        <div class="card">
            <div id="cardContents" class="cardContents3">
                <div class="cardFront"><h2>ABOUT</h2></div>
                <div class="cardBack"><p>The frog sat on the dog...</p></div>
            </div>
        </div>
    
        <div class="card">
            <div id="cardContents" class="cardContents2">
                <div class="cardFront"><h2>A</h2></div>
                <div class="cardBack"><p>Like the dog was a log...</p></div>
            </div>
        </div>
    
        <div class="card">
            <div id="cardContents" class="cardContents1">
                <div class="cardFront"><h2>DOG</h2></div>
                <div class="cardBack"><p>The dog ate the frog...!</p></div>
            </div>
        </div>
    </body>
    </html>