<!--
Design Inspired from Alexander Plyuto
https://dribbble.com/shots/6725201-Smart-Cardholder
-->
<div class="extra-cards-stack">
<div class="card-1"></div>
<div class="card-2"></div>
<div class="card-3"></div>
<div class="card-4"></div>
<div class="card-5"></div>
<div class="card-6"></div>
</div>
<div class="container">
<div class="card-stack">
<div class="balance">
<p>Balance:</p>
<span>$ <span id="balance-counter">3021</span></span>
</div>
<div class="swiper-container">
<div class="slide slide-1">
<div class="bank-name">
<p> monobank | <span>Universal Bank</span></p>
<img src="https://img.icons8.com/bubbles/50/000000/visa.png" />
</div>
<img src="https://img.icons8.com/bubbles/50/000000/sim-card-chip.png" />
<div class="card-number">4505 7389 6378 5628</div>
<div class="personal-info">
<p>Visnu Ravichandran</p>
<p>07/2023</p>
</div>
</div>
<div class="slide slide-2">
<div class="bank-name">
<p> monobank | <span>Town Bank</span></p>
<img src="https://img.icons8.com/color/48/000000/mastercard.png" />
</div>
<img src="https://img.icons8.com/nolan/50/sim-card-chip.png" />
<div class="card-number">4729 7837 9829 7828</div>
<div class="personal-info">
<p>Visnu Ravichandran</p>
<p>02/2022</p>
</div>
</div>
<div class="slide slide-3">
<div class="bank-name">
<p> monobank | <span>Gold Card</span></p>
<img src="https://img.icons8.com/bubbles/50/000000/visa.png" />
</div>
<img src="https://img.icons8.com/bubbles/50/000000/sim-card-chip.png" />
<div class="card-number">4183 9737 1283 0837</div>
<div class="personal-info">
<p>Visnu Ravichandran</p>
<p>05/2025</p>
</div>
</div>
</div>
</div>
</div>
/* ***** Colors - Start ***** */
$black: #111;
$light-black: #242224;
$blue: #1b2f69;
$light-blue: #27408f;
$white: #fff;
$light-white: #dae4ee;
/* ***** Colors - End ***** */
/* ***** Dimensions - Start ***** */
$card-stack-width: 300px;
$card-stack-height: 550px;
$card-width: calc(#{$card-stack-width} - 30px);
$card-height: 200px;
/* ***** Dimensions - End ***** */
/* ***** Global Styles - Start ***** */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
background-color: $black;
overflow: hidden;
}
%center {
display: flex;
justify-content: center;
align-items: center;
}
%extra-cards {
position: absolute;
width: $card-width;
height: $card-height;
background-color: $light-black;
border-radius: 10px;
}
%card {
width: $card-width;
height: $card-height;
border-radius: 10px;
}
/* ***** Global Styles - End ***** */
/* ***** Specific Styles - Start ***** */
.container {
@extend %center;
height: 100vh;
}
.card-1 {
@extend %extra-cards;
top: 10px;
left: -200px;
transform: rotate(-20deg);
}
.card-2 {
@extend %extra-cards;
top: calc(#{$card-width} - 20px);
left: -120px;
transform: rotate(-20deg);
}
.card-3 {
@extend %extra-cards;
top: calc(#{$card-width} * 2 - 50px);
left: -35px;
transform: rotate(-20deg);
}
.card-4 {
@extend %extra-cards;
bottom: 10px;
right: -200px;
transform: rotate(-20deg);
}
.card-5 {
@extend %extra-cards;
bottom: calc(#{$card-width} - 20px);
right: -120px;
transform: rotate(-20deg);
}
.card-6 {
@extend %extra-cards;
bottom: calc(#{$card-width} * 2 - 50px);
right: -35px;
transform: rotate(-20deg);
overflow: hidden;
}
.card-stack {
display: flex;
justify-content: center;
width: $card-stack-width;
height: $card-stack-height;
background-color: $light-black;
border-radius: 20px;
transform: rotate(-20deg);
.balance {
position: absolute;
width: 100%;
margin-top: 230px;
margin-left: 40px;
font-size: 11px;
color: $white;
span {
font-size: 18px;
}
}
}
.swiper-container {
display: flex;
width: $card-width;
height: $card-height;
justify-content: center;
align-self: flex-end;
margin-bottom: 15px;
}
.slide {
position: absolute;
@extend %card;
font-size: 18px;
padding: 20px;
background: #fff;
cursor: pointer;
outline: none;
.bank-name {
display: flex;
justify-content: space-between;
align-items: flex-start;
font-size: 12px;
span {
font-size: 10px;
color: grey;
}
img {
margin: -15px -10px 0 0;
}
}
img {
margin: 10px 0;
}
.card-number {
font-size: 15px;
}
.personal-info {
display: flex;
justify-content: space-between;
margin-top: 10px;
font-size: 12px;
}
&.slide-3 {
width: calc(#{$card-width} - 30px);
margin-top: -30px;
background: rgb(72, 111, 233);
z-index: 1;
color: $white;
span {
color: $white;
opacity: 0.5;
}
}
&.slide-2 {
width: calc(#{$card-width} - 15px);
background-color: $white;
z-index: 2;
}
&.slide-1 {
margin-top: -320px;
z-index: 3;
color: #fff;
background-color: $black;
}
}
/* ***** Specific Styles - End ***** */
/* ***** Media Queries - Start ***** */
@media screen and (max-width: 650px) {
.card-1,
.card-2,
.card-3,
.card-4,
.card-5,
.card-6 {
display: none;
}
}
/* ***** Media Queries - End ***** */
View Compiled
// ***** GSAP Timeline Initialization *****
var animateCard1 = gsap.timeline({ paused: true });
var animateCard2 = gsap.timeline({ paused: true });
var animateCard3 = gsap.timeline({ paused: true });
var selectCard = gsap.timeline({ paused: true });
// ***** GSAP TimelineMax Initialization *****
var animateCurrentCard = new TimelineMax();
var animateExtraCards = new TimelineMax();
// ***** SCSS Parameters *****
const colors = {
$black: "#111",
$lightBlack: "#242224",
$blue: "#1b2f69",
$lightBlue: "#27408f",
$white: "#fff",
$lightWhite: "#dae4ee"
};
const balance = {
$card1: 3021,
$card2: 568,
$card3: 2748
};
const cardPositions = {
$top: {
$marginTop: "-320px"
},
$behind: {
$marginTop: "-30px"
},
$end: {
$marginTop: "0px"
}
};
// ***** Animation Parameters Initialization *****
let rotateAxis = 180;
const duration = 0.5;
// ***** Variables Initialization *****
let extraCardsBackgroundColor = null;
let bodyBackgroundColor = null;
// ***** Function : updateBalance : Start *****
const updateBalance = (updatedValue) => {
var counter = { val:0 };
TweenLite.to(counter, duration ,{
val: updatedValue,
roundProps:"val",
onUpdate:function(){
$("#balance-counter").text(counter.val);
}});
}
// ***** Function : updateBalance : End *****
// ***** Function : setAnimationForExtraCards : Start *****
const setAnimationForExtraCards = () => {
animateExtraCards
.to("body", duration, {
backgroundColor: bodyBackgroundColor
})
.to( ".card-stack", {
backgroundColor: extraCardsBackgroundColor },0)
.to(".card-1",{
rotateX: rotateAxis,
backgroundColor: extraCardsBackgroundColor},0)
.set(".card-1", { rotateX: 0 })
.to(".card-2",{
rotateX: rotateAxis,
backgroundColor: extraCardsBackgroundColor},0)
.set(".card-2", { rotateX: 0 })
.to(".card-3",{
rotateX: rotateAxis,
backgroundColor: extraCardsBackgroundColor},0)
.set(".card-3", { rotateX: 0 })
.to(".card-4",{
rotateX: rotateAxis,
backgroundColor: extraCardsBackgroundColor},0)
.set(".card-4", { rotateX: 0 })
.to(".card-5",{
rotateX: rotateAxis,
backgroundColor: extraCardsBackgroundColor},0)
.set(".card-5", { rotateX: 0 })
.to(".card-6",{
rotateX: rotateAxis,
backgroundColor: extraCardsBackgroundColor},0)
.set(".card-6", { rotateX: 0 });
};
// ***** Function : setAnimationForExtraCards : End *****
// ***** Function : setAnimationForCard1 : Start *****
const setAnimationForCard1 = () => {
const slide2MarginTop = $(".slide-2").css("margin-top");
const slide3MarginTop = $(".slide-3").css("margin-top");
animateCard1
.to(".slide-1", duration, {
ease: "back.inOut(1.7)",
translateY: -200,
width: 270
})
.set(".slide-1", { zIndex: 2 });
if (slide2MarginTop === cardPositions.$end.$marginTop) {
animateCard1
.set(".slide-2", { zIndex: 1 })
.to(".slide-2", duration/2, { ease: "back.inOut(1.7)", marginTop: -30, width: 240 });
}
if (slide3MarginTop === cardPositions.$end.$marginTop) {
animateCard1
.set(".slide-3", { zIndex: 1 })
.to(".slide-3", duration/2, { ease: "back.inOut(1.7)", marginTop: -30, width: 240 });
}
animateCard1
.to(".slide-1", {
ease: "back",
translateY: 0,
marginTop: 0
})
.set(".slide-1", { marginTop: 0, zIndex: 3 });
};
// ***** Function : setAnimationForCard1 : End *****
// ***** Function : setAnimationForCard2 : Start *****
const setAnimationForCard2 = () => {
const slide1MarginTop = $(".slide-1").css("margin-top");
const slide3MarginTop = $(".slide-3").css("margin-top");
animateCard2
.to(".slide-2", duration, {
ease: "back.inOut(1.7)",
translateY: -200,
width: 270
})
.set(".slide-2", { zIndex: 2 });
if (slide1MarginTop === cardPositions.$end.$marginTop) {
animateCard2
.set(".slide-1", { zIndex: 1 })
.to(".slide-1", duration/2, { ease: "back.inOut(1.7)", marginTop: -30, width: 240 });
}
if (slide3MarginTop === cardPositions.$end.$marginTop) {
animateCard2
.set(".slide-3", { zIndex: 1 })
.to(".slide-3", duration/2, { ease: "back.inOut(1.7)", marginTop: -30, width: 240 });
}
animateCard2
.to(".slide-2", {
ease: "back",
translateY: 0,
marginTop: 0
})
.set(".slide-2", { marginTop: 0, zIndex: 3 });
};
// ***** Function : setAnimationForCard2 : End *****
// ***** Function : setAnimationForCard3 : Start *****
const setAnimationForCard3 = () => {
const slide1MarginTop = $(".slide-1").css("margin-top");
const slide2MarginTop = $(".slide-2").css("margin-top");
animateCard3
.to(".slide-3", duration, {
ease: "back.inOut(1.7)",
translateY: -200,
width: 270
})
.set(".slide-3", { zIndex: 2 });
if (slide1MarginTop === cardPositions.$end.$marginTop) {
animateCard3
.set(".slide-1", { zIndex: 1 })
.to(".slide-1", duration/2, { ease: "back.inOut(1.7)", marginTop: -30, width: 240 });
}
if (slide2MarginTop === cardPositions.$end.$marginTop) {
animateCard3
.set(".slide-2", { zIndex: 1 })
.to(".slide-2", duration/2, { ease: "back.inOut(1.7)", marginTop: -30, width: 240 });
}
animateCard3
.to(".slide-3", {
ease: "back",
translateY: 0,
marginTop: 0
})
.set(".slide-3", { marginTop: 0, zIndex: 3 });
};
// ***** Function : setAnimationForCard3 : End *****
// ***** Function : setCurrentCardAnimation : Start *****
const setCurrentCardAnimation = () => {
const slide1MarginTop = $(".slide-1").css("margin-top");
const slide2MarginTop = $(".slide-2").css("margin-top");
const slide3MarginTop = $(".slide-3").css("margin-top");
if (slide1MarginTop === cardPositions.$behind.$marginTop) {
animateCurrentCard
.set(".slide-1", { zIndex: 2 },0)
.to(".slide-1",{
ease: "back",
marginTop: 0,
width: 270
},0);
}
if (slide2MarginTop === cardPositions.$behind.$marginTop) {
animateCurrentCard
.set(".slide-2", { zIndex: 2 }, 0)
.to(".slide-2",{
ease: "back",
marginTop: 0,
width: 270
},0);
}
if (slide3MarginTop === cardPositions.$behind.$marginTop) {
animateCurrentCard
.set(".slide-3", { zIndex: 2 }, 0)
.to(".slide-3", {
ease: "back",
marginTop: 0,
width: 270
},0);
}
if (slide1MarginTop === cardPositions.$top.$marginTop) {
animateCurrentCard
.set(".slide-1", { zIndex: 1 }, 0)
.to(".slide-1",{
ease: "back",
marginTop: -30,
width: 240
},0);
}
if (slide2MarginTop === cardPositions.$top.$marginTop) {
animateCurrentCard
.set(".slide-2", { zIndex: 1 }, 0)
.to(".slide-2",{
ease: "back",
marginTop: -30,
width: 240
},0);
}
if (slide3MarginTop === cardPositions.$top.$marginTop) {
animateCurrentCard
.set(".slide-3", { zIndex: 1 }, 0)
.to(".slide-3",{
ease: "back",
marginTop: -30,
width: 240
},0);
}
};
// ***** Function : setCurrentCardAnimation : End *****
// ***** Event Handlers : Start *****
$(".slide-1").click(function () {
const marginTop = $(this).css("margin-top");
if (marginTop === cardPositions.$behind.$marginTop) {
setAnimationForCard1();
animateCard1.play();
}
if (marginTop === cardPositions.$end.$marginTop) {
selectCard
.to(".slide-1", {
ease: "back",
translateY: -320
})
.set(".slide-1", { translateY: 0, marginTop: -320 })
.restart();
$(".balance").css("color", colors.$white);
updateBalance(balance.$card1);
setCurrentCardAnimation();
extraCardsBackgroundColor = colors.$lightBlack;
bodyBackgroundColor = colors.$black;
setAnimationForExtraCards();
}
});
$(".slide-2").click(function () {
const marginTop = $(this).css("margin-top");
if (marginTop === cardPositions.$behind.$marginTop) {
setAnimationForCard2();
animateCard2.play();
}
if (marginTop === cardPositions.$end.$marginTop) {
selectCard
.to(".slide-2", {
ease: "back",
translateY: -320
})
.set(".slide-2", { translateY: 0, marginTop: -320 })
.restart();
$(".balance").css("color", colors.$black);
updateBalance(balance.$card2);
setCurrentCardAnimation();
extraCardsBackgroundColor = colors.$lightWhite;
bodyBackgroundColor = colors.$white;
setAnimationForExtraCards();
}
});
$(".slide-3").click(function () {
const marginTop = $(this).css("margin-top");
if (marginTop === cardPositions.$behind.$marginTop) {
setAnimationForCard3();
animateCard3.play();
}
if (marginTop === cardPositions.$end.$marginTop) {
selectCard
.to(".slide-3", {
ease: "back",
translateY: -320
})
.set(".slide-3", { translateY: 0, marginTop: -320 })
.restart();
$(".balance").css("color", colors.$white);
updateBalance(balance.$card3);
setCurrentCardAnimation();
extraCardsBackgroundColor = colors.$lightBlue;
bodyBackgroundColor = colors.$blue;
setAnimationForExtraCards();
}
});
// ***** Event Handlers : End *****
// ***** Clearing Timelines : Start *****
animateExtraCards.eventCallback("onComplete", () => {
animateExtraCards.clear();
});
animateCurrentCard.eventCallback("onComplete", () => {
animateCurrentCard.clear();
});
selectCard.eventCallback("onComplete", () => {
selectCard.clear();
});
animateCard1.eventCallback("onComplete", () => {
animateCard1.clear();
});
animateCard2.eventCallback("onComplete", () => {
animateCard2.clear();
});
animateCard3.eventCallback("onComplete", () => {
animateCard3.clear();
});
// ***** Clearing Timelines : End *****