Perspective Deck
Holographic trading cards with iridescent cyan→magenta sheen and pearl borders — click to send the front card receding into the back.
Perspective Deck the 5th of 22 designs in the 22 CSS Stacked Card Designs collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<div class="scd-persp scd-cycle" tabindex="0"> <div class="scd-persp__c" style="--i: 3"><span>015</span></div> <div class="scd-persp__c" style="--i: 2"><span>014</span></div> <div class="scd-persp__c" style="--i: 1"><span>013</span></div> <div class="scd-persp__c" style="--i: 0"><span>012</span></div> </div>
.scd-persp {
position: relative; width: 220px; height: 170px; margin: 0 auto;
perspective: 600px; transform-style: preserve-3d;
cursor: pointer;
}
.scd-persp__c {
position: absolute; left: 50%; top: 50%;
width: 144px; height: 96px; margin: -48px 0 0 -72px;
background:
linear-gradient(115deg, #00ffff 0%, #ff00ff 35%, #00ffff 65%, #ff00ff 100%),
#e6f0ff;
background-size: 220% 100%;
background-position: calc(var(--i) * 28%) center;
border: 2px solid #e6f0ff;
border-radius: 10px;
display: grid; place-items: center;
box-shadow: 0 8px 20px -8px rgba(0,255,255,0.4), inset 0 0 0 1px rgba(255,255,255,0.5);
transform: translateZ(calc(var(--i) * -22px)) translateY(calc(var(--i) * -10px));
filter: brightness(calc(1 - var(--i) * 0.1));
z-index: calc(10 - var(--i));
transition: transform .55s cubic-bezier(.3,1.2,.4,1), filter .4s, z-index 0s .27s;
}
.scd-persp__c span {
font: 900 28px/1 ui-monospace, monospace;
color: #1a0033;
background: rgba(255,255,255,0.85);
padding: 6px 14px; border-radius: 6px;
letter-spacing: 0.06em;
} /* Click-to-cycle the holo deck: front card recedes. */
document.querySelectorAll('.scd-persp.scd-cycle').forEach(function(stack) {
stack.addEventListener('click', function() {
var cards = Array.from(stack.children);
var max = cards.length - 1;
cards.forEach(function(card) {
var current = parseInt(card.style.getPropertyValue('--i') || '0', 10);
var next = current === 0 ? max : current - 1;
card.style.setProperty('--i', next);
});
});
});