Neon Noir
A cyberpunk terminal button glowing faint cyan. Click detonates a plasma burst — an expanding ring, a radial bloom, and ten sparks flung from the point of contact.
Neon Noir the 9th of 43 designs in the 43 CSS Button 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
<button class="btn-neon">Connect</button>
.btn-neon {
position: relative;
padding: 16px 36px;
border: 1px solid rgba(0,255,249,0.3);
background: rgba(0,255,249,0.04);
color: #00fff9;
font-family: ui-monospace, "SF Mono", Menlo, monospace;
font-size: 11px;
font-weight: 700;
letter-spacing: 3px;
text-transform: uppercase;
cursor: pointer;
overflow: hidden;
user-select: none;
box-shadow: 0 0 20px rgba(0,255,249,0.05), inset 0 0 20px rgba(0,255,249,0.02);
transition: border-color 0.3s, background 0.3s, box-shadow 0.3s, color 0.3s;
}
.btn-neon:hover {
border-color: rgba(0,255,249,0.8);
background: rgba(0,255,249,0.08);
box-shadow: 0 0 30px rgba(0,255,249,0.2), inset 0 0 30px rgba(0,255,249,0.05);
color: #fff;
}
.btn-neon-plasma,
.btn-neon-ring {
position: absolute;
border-radius: 50%;
transform: scale(0);
pointer-events: none;
}
.btn-neon-plasma {
background: radial-gradient(circle, rgba(0,255,249,0.8) 0%, rgba(0,120,255,0.4) 40%, transparent 70%);
mix-blend-mode: screen;
animation: btn-neon-burst 0.7s cubic-bezier(.22,1,.36,1) forwards;
}
.btn-neon-ring {
border: 2px solid rgba(0,255,249,0.6);
animation: btn-neon-ring 0.7s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes btn-neon-burst {
0% { transform: scale(0); opacity: 1; }
60% { opacity: 0.6; }
100% { transform: scale(5); opacity: 0; }
}
@keyframes btn-neon-ring {
0% { transform: scale(0); opacity: 1; }
100% { transform: scale(4); opacity: 0; }
}
.btn-neon-spark {
position: absolute;
width: 2px;
height: 2px;
border-radius: 50%;
background: #00fff9;
pointer-events: none;
animation: btn-neon-spark 0.6s ease-out forwards;
}
@keyframes btn-neon-spark {
0% { transform: translate(0,0) scale(1); opacity: 1; }
100% { transform: translate(var(--sx), var(--sy)) scale(0); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.btn-neon-plasma, .btn-neon-ring, .btn-neon-spark { animation: none; display: none; }
} document.querySelectorAll('.btn-neon').forEach(function (btn) {
btn.addEventListener('click', function (e) {
var r = btn.getBoundingClientRect();
var x = e.clientX - r.left;
var y = e.clientY - r.top;
var size = Math.max(r.width, r.height) * 0.8;
['btn-neon-plasma', 'btn-neon-ring'].forEach(function (cls) {
var el = document.createElement('div');
el.className = cls;
el.style.width = size + 'px';
el.style.height = size + 'px';
el.style.left = (x - size / 2) + 'px';
el.style.top = (y - size / 2) + 'px';
btn.appendChild(el);
el.addEventListener('animationend', function () { this.remove(); });
});
for (var i = 0; i < 10; i++) {
var s = document.createElement('span');
s.className = 'btn-neon-spark';
var angle = (i / 10) * Math.PI * 2;
var dist = 30 + Math.random() * 50;
s.style.left = x + 'px';
s.style.top = y + 'px';
s.style.setProperty('--sx', (Math.cos(angle) * dist) + 'px');
s.style.setProperty('--sy', (Math.sin(angle) * dist) + 'px');
s.style.animationDelay = (Math.random() * 0.1) + 's';
btn.appendChild(s);
s.addEventListener('animationend', function () { this.remove(); });
}
});
});