Back to CSS Badges Holographic Collectible Pure CSS
Share
HTML
<div class="holo-card">
  <div class="holo-badge holo-mythic">
    <div class="holo-face holo-base"></div>
    <div class="holo-face holo-foil"></div>
    <div class="holo-face holo-sheen"></div>
    <div class="holo-face holo-edge"></div>
    <div class="holo-glyph">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
        <path d="M12 1l3 6 7 1-5 5 1 7-6-3-6 3 1-7-5-5 7-1z"/>
      </svg>
      <div class="holo-rarity">RARITY</div>
      <div class="holo-tier">MYTHIC</div>
    </div>
    <div class="holo-serial">#00007 / 00050</div>
  </div>
  <div class="holo-name">The Ascendant</div>
  <div class="holo-pop">POP 44</div>
</div>
CSS
.holo-card {
  background: radial-gradient(ellipse at 50% 50%, #0e0a1a 0%, #050208 100%);
  padding: 56px 40px;
  font-family: 'Geist Mono', ui-monospace, monospace;
  text-align: center;
  min-height: 360px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.holo-badge {
  width: 200px;
  height: 230px;
  margin: 0 auto 24px;
  position: relative;
  cursor: pointer;
  --mx: 50%;
  --my: 50%;
}
.holo-face {
  position: absolute;
  inset: 0;
  clip-path: polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%);
}
.holo-base {
  background: linear-gradient(135deg, #1a1230 0%, #0a0815 100%);
  box-shadow: inset 0 0 20px rgba(255,255,255,0.05);
}
.holo-foil {
  background:
    conic-gradient(from var(--angle, 0deg) at var(--mx) var(--my),
      #ff0080, #ff8c00, #ffd700, #00ff88, #00bfff, #8a2be2, #ff0080);
  mix-blend-mode: screen;
  opacity: 0.75;
  transition: opacity 0.4s;
  filter: saturate(1.3) blur(0.4px);
}
.holo-sheen {
  background: radial-gradient(circle 80px at var(--mx) var(--my),
    rgba(255,255,255,0.6), transparent 70%);
  mix-blend-mode: overlay;
  opacity: 0;
  transition: opacity 0.4s;
}
.holo-edge {
  background: linear-gradient(135deg,
    rgba(255,215,140,0.6) 0%,
    rgba(180,140,255,0.4) 50%,
    rgba(120,200,255,0.6) 100%);
  clip-path: polygon(
    50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%,
    5% 27%, 7% 26%, 7% 74%, 50% 97%, 93% 74%, 93% 26%, 50% 3%
  );
}
.holo-badge:hover .holo-foil { opacity: 1; }
.holo-badge:hover .holo-sheen { opacity: 1; }
.holo-glyph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #fff;
  z-index: 2;
  text-shadow: 0 0 12px rgba(255,255,255,0.3);
  pointer-events: none;
}
.holo-glyph svg { width: 56px; height: 56px; margin-bottom: 8px; }
.holo-rarity {
  font-size: 10px;
  letter-spacing: 0.3em;
  opacity: 0.85;
  margin-bottom: 2px;
}
.holo-tier {
  font-size: 16px;
  letter-spacing: 0.18em;
  font-weight: 600;
}
.holo-serial {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 8px;
  letter-spacing: 0.2em;
  color: rgba(255,255,255,0.6);
  z-index: 2;
}
.holo-name {
  font-family: Georgia, serif;
  color: #f5f0e0;
  font-size: 20px;
  font-style: italic;
  margin-bottom: 4px;
}
.holo-pop {
  font-size: 10px;
  letter-spacing: 0.2em;
  color: rgba(255,255,255,0.4);
  text-transform: uppercase;
}
.holo-mythic .holo-base {
  animation: holo-mythic-pulse 3s ease-in-out infinite;
}
@keyframes holo-mythic-pulse {
  0%, 100% {
    box-shadow: inset 0 0 20px rgba(255,100,255,0.2),
                0 0 30px rgba(255,100,255,0.2);
  }
  50% {
    box-shadow: inset 0 0 40px rgba(255,100,255,0.5),
                0 0 60px rgba(255,100,255,0.4);
  }
}
@media (prefers-reduced-motion: reduce) {
  .holo-mythic .holo-base { animation: none; }
}
JS
// Cursor-tracked foil. Updates two CSS custom properties on the
// .holo-badge so the conic gradient and the sheen highlight follow
// the pointer. mouseleave resets so the badge isn't stuck mid-tilt.
document.querySelectorAll('.holo-badge').forEach(function (badge) {
  badge.addEventListener('mousemove', function (e) {
    var r = badge.getBoundingClientRect();
    var x = ((e.clientX - r.left) / r.width) * 100;
    var y = ((e.clientY - r.top) / r.height) * 100;
    badge.style.setProperty('--mx', x + '%');
    badge.style.setProperty('--my', y + '%');
    badge.style.setProperty('--angle', (x * 3.6) + 'deg');
  });
  badge.addEventListener('mouseleave', function () {
    badge.style.setProperty('--mx', '50%');
    badge.style.setProperty('--my', '50%');
  });
});