Overlaping Effect on Cards with Pure CSS

Viewed 75

I'm working on a list of cards similar to this example: https://codepen.io/pkunzel/pen/xxgjrVg

window.addEventListener("load", function() {
  let cards = document.querySelectorAll(".card");
  for (let i = 0; i < cards.length; i++) {
    cards[i].style.marginTop = (i * 30) + "px";
  }
});
.card {
  position: absolute;
}

.blue {
  background-color: cornflowerblue;
}

.green {
  background-color: darkolivegreen;
}

.red {
  background-color: lightcoral;
}

.orange {
  background-color: lightsalmon;
}
<div class="card-group">
  <div class="card blue">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card red">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card green">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card orange">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
</div>

But after completing it I can't shake off the feeling it could purely with CSS, I just can't figure out how to implement it differently. Any suggestions?

3 Answers

CSS grid can do it:

.card-group {
  display:grid;
  justify-content:start; /* fit content in width */
  grid-auto-rows:30px; /* a fixed height to create an overflow */ 
}
.card-group .card {
  align-self:start; /* disable the stretch alignment */
}
.blue {
  background-color: cornflowerblue;
}

.green {
  background-color: darkolivegreen;
}

.red {
  background-color: lightcoral;
}

.orange {
  background-color: lightsalmon;
}
<div class="card-group">
  <div class="card blue">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card red">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card green">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card orange">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
</div>

You can do something like this using a css-variables:

:root {
  --mt: 30px;
}

.card {
  position: absolute;
}

.blue {
  background-color: cornflowerblue;
}

.red {
  background-color: lightcoral;
  margin-top: var(--mt);
}

.green {
  background-color: darkolivegreen;
  margin-top: calc(var(--mt)*2);
}

.orange {
  background-color: lightsalmon;
  margin-top: calc(var(--mt)*3);
}
<div class="card-group">
  <div class="card blue">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card red">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card green">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
  <div class="card orange">
    <p>Name: qwert</p>
    <p>Age: 99</p>
    <p>Address: qwertyuil</p>
  </div>
</div>

I prefer this way, just add .card-wrapper before your card and give specify height of the card-wrapper, then the card will be stacked up.

here my fiddle

<div class="card-group">
  <div class="card-wrapper">
     <div class="card blue">
      <p>Name: qwert</p>
      <p>Age: 99</p>
      <p>Address: qwertyuil</p>
    </div>
  </div>
  
  <div class="card-wrapper">
    <div class="card red">
      <p>Name: qwert</p>
      <p>Age: 99</p>
      <p>Address: qwertyuil</p>
    </div>
  </div>
  <div class="card-wrapper">
    <div class="card green">
      <p>Name: qwert</p>
      <p>Age: 99</p>
      <p>Address: qwertyuil</p>
    </div>
  </div>
  <div class="card-wrapper">
    <div class="card orange">
      <p>Name: qwert</p>
      <p>Age: 99</p>
      <p>Address: qwertyuil</p>
    </div>
  </div>
</div>

.card-wrapper{
  height: 10px;
  width: fit-content;
}
.card-wrapper:hover{
  height: 150px;
}
.card {
  position: absolute;
}

.blue {
  background-color: cornflowerblue;
}

.green {
  background-color: darkolivegreen;
}

.red {
  background-color: lightcoral;
}

.orange {
  background-color: lightsalmon;
}
Related