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.
<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>
: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;
}
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");
});
});