Quick Tip: How to Build a Simple Stack Hover Effect With CSS

Uncategorized

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):

1. Begin With the HTML Markup

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

2. Define the Styles

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:

The stacking effect with pseudo-elements

And here’s the layout when those variables double their values:

The stacking effect with pseudo-elements

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);
}

Conclusion

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:

Have you ever implemented this kind of layout? If so, what technique did you use? Join the discussion in the comments below!

As always, thanks a lot for reading!

Next Level CSS Hover Effects

Original Article

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.