How to create responsive stacked cards hover effect using CSS ?

25 Aug, 2021
Introduction: Cards are a very important part of any website. It is used to display some important information in short to viewers. In this article, we will create responsive stackend cards hover effect using HTML and CSS. In order to achieve a multi-layer stacking effect, you have to follow certain steps which are given below.
Note: Through hover on cards, we can achieve various directions or effects on cards like top-left, bottom-right, diagonal, rotate, etc.
Approach: First, we will design a simple card structure in HTM.  Now we will use some CSS properties to build the basic design of the card and to create a stack effect, we will define the ::before and ::after pseudo-elements and absolutely position them relative to the parent card. Now we will have to move the div with class “card-inner” away from its original position by using the transform property. Finally, added a hover effect on a stack of cards by using a transform that can translate the card before and after the hover effect.
Let’s see the implementation of the above approach.
Example 1: In this example,  we will see when the user will hover over the card Top Card will translate over X-axis and Y-axis, here (5px-X-axis, 5px-Y-axis) bottom-right direction and below stacked card will translate (-X)-axis and (-Y)-axis i.e opposite to bottom-right direction which will create multiple stacked-bottom-right effects will the help of before and after Pseudo element.
HTML
<!DOCTYPE html><html>  <head>    <title> stackened cards hover effect </title>    <style>        body {            color: #FDFAF6;            background: #50CB93;        }          .card {            position: relative;            width: 400px;            margin: 60px auto;        }          .card::before,        .card::after {            content: "";            position: absolute;            top: 0;            left: 0;            width: 100%;            height: 100%;        }          .card::before,        .card::after,        .card .card-inner {            background-color: #423F3E;            border: 1px solid #01937C;            transition: transform 0.5s;        }          .card::before,        .card-inner {            z-index: 1;        }          .card-inner {            position: relative;            padding: 4rem;        }          /* Position the stacked cards in         different position */        .cards:hover {            transform: translate(5px, 5px);        }          .cards:hover::before {            transform: translate(-5px, -5px);        }          .cards:hover::after {            transform: translate(-10px, -10px);        }    </style></head>  <body>    <center>        <h1>Welcome to GeeksforGeeks</h1>        <div class="card-container">            <div class="card cards">                <div class="card-inner">                    <h1>Down-Right</h1>                    <h3 class="card-title">                        GeeksforGeeks                    </h3>                    <div class="card-body">                        A Complete Portal for Geeks.                    </div>                </div>            </div>        </div>    </center></body>  </html>
Output:
Example 2: In this example, we will see stacked-diagonal-left and stacked-rotate-left using the same approach as explained above.
Stacked-Rotate-left:
Top Card will translate only over X-axis , here ( translate(2.5px, 0) ) left direction, and rotate at certain angle, here its 2.5 degree ( rotate(2.5deg) ) .thenBelow stacked card will also translate and rotate in the same direction but with double pixel to create a stacked multi-layer effect with the help of before and after Pseudo element.
Top Card will translate only over X-axis , here ( translate(2.5px, 0) ) left direction, and rotate at certain angle, here its 2.5 degree ( rotate(2.5deg) ) .then
Below stacked card will also translate and rotate in the same direction but with double pixel to create a stacked multi-layer effect with the help of before and after Pseudo element.
Stacked-diagonal-left:
In diagonal-left, Initially multi-layer stack card is positioned in opposite direction to the directional-left ( translate(-16px, -16px) ) using transform:translate property and thenWhen the user hovers over the card, stacked multi-layer card will translate to diagonal-left direction using same value i.e ( translate(16px, 16px)  ) but opposite sign so that stacked multi-layer cards can cover equal direction.
In diagonal-left, Initially multi-layer stack card is positioned in opposite direction to the directional-left ( translate(-16px, -16px) ) using transform:translate property and then
When the user hovers over the card, stacked multi-layer card will translate to diagonal-left direction using same value i.e ( translate(16px, 16px)  ) but opposite sign so that stacked multi-layer cards can cover equal direction.
HTML
<!DOCTYPE html><html>  <head>    <style>        body {            color: #FDFAF6;            background: #50CB93;        }          :root {            --offset-before: 8px;            --offset-after: 16px;        }          .card {            position: relative;            width: 400px;            margin: 60px auto;        }          .card::before,        .card::after {            content: "";            position: absolute;            top: 0;            left: 0;            width: 100%;            height: 100%;        }          .card::before,        .card::after,        .card .card-inner {            background-color: #423F3E;            border: 1px solid #01937C;            transition: transform 0.5s;        }          .card::before,        .card-inner {            z-index: 1;        }          .card-inner {            position: relative;            padding: 4rem;        }          /*Diagonal => Left*/        .cards-diagonal::before {            transform: translate(calc(-1 * 8px),                    calc(-1 * 8px));        }          .cards-diagonal::after {            transform: translate(calc(-1 * 16px),                    calc(-1 * 16px));        }          .cards-diagonal:hover::before {            transform: translate(8px, 8px);        }          .cards-diagonal:hover::after {            transform: translate(16px, 16px);        }          /*Rotate => Left */        .cards-rotate::before,        .cards-rotate::after {            transform-origin: 50% 100%;        }          .cards-rotate:hover {            transform: translate(2.5px, 0) rotate(2.5deg);        }          .cards-rotate:hover::before {            transform: translate(2.5px, 0) rotate(2.5deg);        }          .cards-rotate:hover::after {            transform: translate(5px, 0) rotate(5deg);        }        }    </style></head>  <body>    <center>        <h1>Welcome to GeeksforGeeks</h1>        <div class="card-container">            <div class="card cards-diagonal">                <div class="card-inner">                    <h1>Diagonal-Left</h1>                    <h3 class="card-title">GeeksforGeeks</h3>                    <div class="card-body">                        A Complete Portal for Geeks.                    </div>                </div>            </div>        </div>        <div class="card-container">            <div class="card cards-rotate">                <div class="card-inner">                    <h1>Rotate-Left</h1>                    <h3 class="card-title">GeeksforGeeks</h3>                    <div class="card-body">                        A Complete Portal for Geeks.                    </div>                </div>            </div>        </div>    </center></body>  </html>
Output:
Example 3: In this example, we will see stacked-Up and stacked-Right effects using the same approach as explained above.
Stacked-Up:
Top Card will translate only in negative Y-axis , here (translate(0, -5px)) Up direction, thenbelow stacked card will translate positive Y-axis i.e opposite to Up direction and it will also scale along Y-axis which will create multiple stacked-Up effects with the help of before and after Pseudo element.
Top Card will translate only in negative Y-axis , here (translate(0, -5px)) Up direction, then
below stacked card will translate positive Y-axis i.e opposite to Up direction and it will also scale along Y-axis which will create multiple stacked-Up effects with the help of before and after Pseudo element.
Stacked-Right:
Top Card will translate only in positive X-axis , here ( translate(5px, 0) ) Right direction, thenbelow stacked card will translate negative X-axis (  translate(-10px, 0)  )  i.e opposite to right direction and it will also scale along negative X-axis which will create multiple stacked-Up effects with the help of before and after Pseudo element.
Top Card will translate only in positive X-axis , here ( translate(5px, 0) ) Right direction, then
below stacked card will translate negative X-axis (  translate(-10px, 0)  )  i.e opposite to right direction and it will also scale along negative X-axis which will create multiple stacked-Up effects with the help of before and after Pseudo element.
HTML
<!DOCTYPE html><html>  <head>    <style>        body {            color: #FDFAF6;            background: #50CB93;        }          :root {            --offset-before: 8px;            --offset-after: 16px;        }          .card {            position: relative;            width: 400px;            margin: 60px auto;        }          .card::before,        .card::after {            content: "";            position: absolute;            top: 0;            left: 0;            width: 100%;            height: 100%;        }          .card::before,        .card::after,        .card .card-inner {            background-color: #423F3E;            border: 1px solid #01937C;            transition: transform 0.5s;        }          .card::before,        .card-inner {            z-index: 1;        }          .card-inner {            position: relative;            padding: 4rem;        }          /*Stacked => Up*/        .cards-up::before,        .cards-up::after {            transform-origin: center bottom;        }          .cards-up:hover {            transform: translate(0, -5px);        }          .cards-up:hover::before {            transform: translate(0, 5px) scale(0.95);        }          .cards-up:hover::after {            transform: translate(0, 10px) scale(0.90);        }          /*Stacked => Right */        .cards-right::before,        .cards-right::after {            transform-origin: left center;        }          .cards-right:hover {            transform: translate(5px, 0);        }          .cards-right:hover::before {            transform: translate(-10px, 0) scale(0.95);        }        }          .cards-right:hover::after {            transform: translate(-10px, 0) scale(0.90);        }        }    </style></head>  <body>    <center>        <h1>Welcome to GeeksforGeeks</h1>        <div class="card-container">            <div class="card cards-up">                <div class="card-inner">                    <h1>Stacked-Up</h1>                    <h3 class="card-title">GeeksforGeeks</h3>                    <div class="card-body">                        A Complete Portal for Geeks.                    </div>                </div>            </div>        </div>        <div class="card-container">            <div class="card cards-right">                <div class="card-inner">                    <h1>Stacked-Right</h1>                    <h3 class="card-title">GeeksforGeeks</h3>                    <div class="card-body">                        A Complete Portal for Geeks.                    </div>                </div>            </div>        </div>    </center></body>  </html>
Output:
CSS-Properties
CSS-Questions
HTML-Attributes
HTML-Questions
HTML-Tags
CSS
HTML
Web Technologies
HTML
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Design a Tribute Page using HTML & CSS
How to set space between the flexbox ?
Build a Survey Form using HTML and CSS
Form validation using jQuery
Design a web page using HTML and CSS
REST API (Introduction)
Hide or show elements in HTML using display property
How to set the default value for an HTML <select> element ?
How to set input type date in dd-mm-yyyy format using HTML ?
HTTP headers | Content-Type