<div class="demo-info">
<h2>Fanned Card Deck</h2>
<p>Each card's <code>transform</code> is calculated based on its index relative to the center of the stack. Uses <code>calc()</code> with <code>sibling-index()</code> and <code>sibling-count()</code>.</p>
<div class="controls">
<button id="add-item">Deal one! 🤚</button>
<button id="remove-item">Burn one! 🔥</button>
</div>
</div>
<div class="hand">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
:root {
--card-width: min(30vw, 200px);
--card-height: min(42vw, 280px);
}
.hand {
position: relative;
width: var(--card-width);
height: var(--card-height);
margin-inline: auto;
}
.card {
--rotation-per-card: 8deg;
--center-index: calc((sibling-count() + 1) / 2);
position: absolute;
width: 100%;
height: 100%;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
border: 3px solid white;
transform: rotate(
calc(var(--rotation-per-card) * (sibling-index() - var(--center-index)))
)
translateY(calc(4px * (sibling-index() - 1)));
transform-origin: bottom center;
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
background-image: repeating-linear-gradient(
-45deg,
transparent,
transparent 15px,
#f7b267 15px,
#f7b267 50%
),
repeating-linear-gradient(
45deg,
#f25c54,
#f25c54 15px,
#f79d65 15px,
#f79d65 50%
);
background-size: 30px 30px, 22px 22px;
}
.hand:hover .card {
transform: rotate(
calc(var(--rotation-per-card) * (sibling-index() - var(--center-index)))
)
translateY(calc(-5px * abs(sibling-index() - var(--center-index))));
}
.card--added {
animation: deal-in 0.5s cubic-bezier(0.2, 1, 0.4, 1);
}
.card--removing {
animation: deal-out 0.2s linear;
}
@keyframes deal-in {
from {
opacity: 0;
transform: translateY(100px) rotate(0deg);
}
}
@keyframes deal-out {
to {
opacity: 0;
transform: translateY(-100px) rotate(-5deg);
}
}
@layer basestyles {
:root {
--casino-green-dark: #1d3a2d;
--casino-green-light: #3a7559;
--text-color-light: #f0f0f0;
--button-red: #a31f1f;
--button-gold: #daa520;
}
body {
font-family: "Poppins", sans-serif;
background-color: var(--casino-green-dark);
background-image: radial-gradient(
circle,
var(--casino-green-light) 0%,
var(--casino-green-dark) 100%
);
color: var(--text-color-light);
margin: 0;
padding: 3rem 1rem;
display: grid;
gap: 3.5rem;
justify-items: center;
min-height: 100vh;
box-sizing: border-box;
}
.demo-info {
max-width: 650px;
text-align: center;
}
.demo-container h2 {
margin-bottom: 0.5rem;
}
p code {
background-color: rgba(0, 0, 0, 0.3);
color: #ffd700;
padding: 0.2em 0.4em;
border-radius: 4px;
font-size: 0.9em;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.controls {
margin-top: 2rem;
}
button {
font-family: inherit;
font-size: 1rem;
font-weight: 600;
padding: 0.75rem 1.5rem;
background-color: var(--button-red);
border: 2px solid var(--button-gold);
color: white;
border-radius: 8px;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease,
background-color 0.2s ease;
margin: 0 0.5rem 1.5rem;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
&:hover {
transform: translateY(-3px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.5);
background-color: #c62828; /* Slightly brighter red on hover */
}
&:active {
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
}
}
const hand = document.querySelector(".hand");
const addItem = document.getElementById("add-item");
const removeItem = document.getElementById("remove-item");
addItem.addEventListener("click", () => {
if (hand.children.length < 53) {
const newCard = document.createElement("div");
newCard.classList.add("card");
newCard.classList.add("card--added");
newCard.addEventListener(
"animationend",
() => {
newCard.classList.remove("card--added");
},
{ once: true }
);
hand.appendChild(newCard);
}
});
removeItem.addEventListener("click", () => {
const cardToRemove = hand.lastElementChild;
cardToRemove.classList.add("card--removing");
cardToRemove.addEventListener(
"animationend",
() => {
cardToRemove.remove();
},
{ once: true }
);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.