Card Beam Animation

Card Beam Animation

This page displays the live demo of the card beam animation and lets you view the HTML, CSS, and JavaScript source code used to create it.

HTML

<main class="card-demo">
  <section class="card-grid">
    <article class="card">
      <h2 class="card-title">Quantum UI</h2>
      <p class="card-body">
        Next-gen UI framework designed for speed, interactivity, and effortless scalability.
      </p>
    </article>

    <article class="card">
      <h2 class="card-title">Pulse Metrics</h2>
      <p class="card-body">
        Real-time dashboards with smooth card beam effects on hover.
      </p>
    </article>
  </section>
</main>
            
CSS

:root {
  --bg: #020617;
  --card-bg: radial-gradient(circle at top left, #1f2937, #020617);
}

body {
  margin: 0;
  min-height: 100vh;
  background: radial-gradient(circle at top left, #1f2937, #020617 55%, #020617);
  color: #e5e7eb;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "JetBrains Mono", monospace;
}

.card-demo {
  display: flex;
  justify-content: center;
  padding: 32px 16px;
}

.card-grid {
  display: grid;
  gap: 18px;
  width: min(640px, 100%);
}

.card {
  position: relative;
  padding: 18px 20px 22px;
  border-radius: 18px;
  background: var(--card-bg);
  overflow: hidden;
  border: 1px solid rgba(148, 163, 184, 0.45);
}

/* beam layer */
.card::before {
  content: "";
  position: absolute;
  inset: -40%;
  background:
    radial-gradient(circle at var(--mx, 50%) var(--my, 0%),
    rgba(56, 189, 248, 0.30),
    transparent 60%);
  opacity: 0.9;
  mix-blend-mode: screen;
  transition: opacity 0.35s ease;
  pointer-events: none;
}

.card:hover::before {
  opacity: 1;
}

.card-title {
  font-size: 1.05rem;
  margin-bottom: 0.25rem;
}

.card-body {
  font-size: 0.9rem;
  opacity: 0.9;
}
            
JavaScript

const cards = document.querySelectorAll(".card");

cards.forEach(card => {
  card.addEventListener("mousemove", (event) => {
    const rect = card.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;

    card.style.setProperty("--mx", `${x}px`);
    card.style.setProperty("--my", `${y}px`);
  });

  card.addEventListener("mouseleave", () => {
    card.style.removeProperty("--mx");
    card.style.removeProperty("--my");
  });
});