CSS Stacked Cards Hover Effects
A commonly seen design pattern is to have a card container with other cards underneath it, resulting in a multi-layer stacking effect. Then, during the hover state, the cards smoothly disappear or change their default position. In this short tutorial, we’ll learn a simple CSS technique for creating such an effect.
As usual, let’s have a first look at our demo (scroll through to see all the examples):
We’ll start with the .card-wrapper
element which will include all the cards.
Each card, which is represented by the card
class, will contain the .card-inner
element. Inside that element, we’ll put the contents of the target card:
<div class="card-wrapper">
<div class="card">
<div class="card-inner">
<h3 class="card-title">...</h3>
<div class="card-body">...</div>
</div>
<!-- more cards here -->
</div>
Depending on the hover effect we want to achieve, each class will receive one of the following classes:
card-top-left
card-top-right
card-bottom-left
card-bottom-right
card-diagonal-from-right
card-diagonal-from-left
card-rotate
card-perspective
card-origin
With the markup ready, we’ll set up a few CSS variables and reset styles:
:root {
--body-text-color: #5c5957;
--body-bg-color: #e2d9d5;
--card-border-color: #e2d9d5;
--card-bg-color: #fff;
--offset-before: 8px;
--offset-after: 16px;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
color: var(--body-text-color);
background: var(--body-bg-color);
}
To create the stacking effect, we’re going to take advantage of the pseudo-elements. For each card we’ll define the ::before
and ::after
pseudo-elements and absolutely position them relative to the parent card.
Next, we’ll move them away from their original position by using the transform
property. For the first six examples in the demo, the amount of this reposition will be determined by the offset-before
and offset-after
variables.
Another thing to note is that we give z-index: 1
to all .card-inner
elements so that they always sit on top of their pseudo-elements.
Here’s the card layout when the value of the offset-before
variable is 8px and the value of the offset-after
variable is 16px:
And here’s the layout when those variables double their values:
The required CSS styles for creating the card layout:
/*VARIABLES HERE*/
.card {
position: relative;
cursor: pointer;
max-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: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 5px;
transition: transform 0.3s;
}
.card::before,
.card-inner {
z-index: 1;
}
.card-inner {
position: relative;
padding: 3rem;
}
As said, each card includes a second class that handles its initial offsets along with the hover effect. For example, here are the extra rules that fire for a card that contains the card-top-left
class:
/*CUSTOM VARIABLES HERE*/
.card-top-left::before {
transform: translate(
calc(-1 * var(--offset-before)),
calc(-1 * var(--offset-before))
);
}
.card-top-left::after {
transform: translate(
calc(-1 * var(--offset-after)),
calc(-1 * var(--offset-after))
);
}
.card-top-left:hover::before,
.card-top-left:hover::after,
.card-top-left:hover .card-inner {
transform: translate(calc(-1 * var(--offset-before)), 0);
}
And we’re done, folks! In this quick tutorial, we went through a simple CSS approach for creating card stack hover effects.
Here’s a reminder of what we built:
As always, thanks a lot for reading!
#css #html #web-development #programming #developer