31 examples Responsive beginner

31 CSS Buttons

31 hand-coded CSS buttons — gradients, glassmorphism, 3D press, neon glow, glitch, ripple and more. Every button includes a live demo and a one-click copy snippet.

31 unique buttons 26 Pure CSS 5 CSS + JS 0 dependencies 100% copy-paste ready
01 / 31
Gradient Fill
Pure CSS
Smooth linear-gradient background with a brightness lift on hover.
.btn-gfill {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(135deg, #7c6cff, #a78bfa);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.2s, transform 0.15s;
}
.btn-gfill:hover {
  filter: brightness(1.15);
  transform: translateY(-1px);
}
<button class="btn-gfill">Get Started</button>
02 / 31
Outline Pulse
Pure CSS
Transparent outline button whose border pulses outward as a ripple on hover.
.btn-outline-pulse {
  padding: 12px 28px;
  border: 2px solid #7c6cff;
  border-radius: 8px;
  background: transparent;
  color: #7c6cff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  transition: color 0.2s;
}
.btn-outline-pulse::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 10px;
  border: 2px solid #7c6cff;
  opacity: 0;
  transform: scale(1);
  transition: transform 0.4s, opacity 0.4s;
}
.btn-outline-pulse:hover::after {
  transform: scale(1.18);
  opacity: 0;
  animation: opulse 0.55s ease-out forwards;
}
@keyframes opulse {
  0%   { transform: scale(1);    opacity: 0.7; }
  100% { transform: scale(1.22); opacity: 0; }
}
<button class="btn-outline-pulse">Subscribe</button>
03 / 31
Glass Morph
Pure CSS
Frosted-glass button using backdrop-filter blur with a subtle border.
.btn-glass {
  padding: 12px 28px;
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: 10px;
  background: rgba(255,255,255,0.08);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: #fff;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}
.btn-glass:hover {
  background: rgba(255,255,255,0.16);
  border-color: rgba(255,255,255,0.38);
}
<button class="btn-glass">Learn More</button>
04 / 31
3D Press
Pure CSS
A chunky 3D button that physically sinks down when pressed using box-shadow and translateY.
.btn-3d {
  padding: 13px 30px;
  border: none;
  border-radius: 8px;
  background: #7c6cff;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 6px 0 #4b3fd4;
  transform: translateY(0);
  transition: transform 0.1s, box-shadow 0.1s;
}
.btn-3d:hover { filter: brightness(1.08); }
.btn-3d:active {
  transform: translateY(4px);
  box-shadow: 0 2px 0 #4b3fd4;
}
<button class="btn-3d">Push Me</button>
05 / 31
Neon Glow
Pure CSS
Dark button with a coloured neon box-shadow that intensifies on hover.
.btn-neon {
  padding: 12px 28px;
  border: 2px solid #2ecc8a;
  border-radius: 8px;
  background: transparent;
  color: #2ecc8a;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 0 8px rgba(46,204,138,0.35);
  transition: box-shadow 0.25s, background 0.25s, color 0.25s;
}
.btn-neon:hover {
  background: rgba(46,204,138,0.12);
  box-shadow: 0 0 18px rgba(46,204,138,0.6), 0 0 40px rgba(46,204,138,0.25);
  color: #fff;
}
<button class="btn-neon">Explore</button>
06 / 31
Slide Fill
Pure CSS
The background slides in from the left on hover, swapping colours smoothly.
.btn-slide-fill {
  padding: 12px 28px;
  border: 2px solid #7c6cff;
  border-radius: 8px;
  background: transparent;
  color: #7c6cff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  z-index: 0;
  transition: color 0.3s;
}
.btn-slide-fill::before {
  content: '';
  position: absolute;
  inset: 0;
  background: #7c6cff;
  transform: translateX(-101%);
  transition: transform 0.3s ease;
  z-index: -1;
}
.btn-slide-fill:hover { color: #fff; }
.btn-slide-fill:hover::before { transform: translateX(0); }
<button class="btn-slide-fill">Read More</button>
07 / 31
Icon Arrow
Pure CSS
Text button with an arrow that slides in from the left on hover.
.btn-arrow {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: #18181f;
  color: #a78bfa;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: gap 0.2s, background 0.2s;
}
.btn-arrow::after {
  content: '→';
  display: inline-block;
  transition: transform 0.2s;
}
.btn-arrow:hover {
  gap: 12px;
  background: #1f1f2e;
}
.btn-arrow:hover::after { transform: translateX(4px); }
<button class="btn-arrow">Continue</button>
08 / 31
Ripple Click
CSS + JS
A radial ripple expands from the click point using a CSS animation on ::after.
.btn-ripple {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: #7c6cff;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.btn-ripple .ripple-circle {
  position: absolute;
  border-radius: 50%;
  background: rgba(255,255,255,0.35);
  transform: scale(0);
  animation: ripple-grow 0.55s linear;
  pointer-events: none;
}
@keyframes ripple-grow {
  to { transform: scale(4); opacity: 0; }
}
<button class="btn-ripple">Click Me</button>
document.querySelectorAll('.btn-ripple').forEach(function(btn) {
  btn.addEventListener('click', function(e) {
    var circle = document.createElement('span');
    var rect = btn.getBoundingClientRect();
    var size = Math.max(rect.width, rect.height);
    circle.className = 'ripple-circle';
    circle.style.cssText = 'width:' + size + 'px;height:' + size + 'px;left:' + (e.clientX - rect.left - size/2) + 'px;top:' + (e.clientY - rect.top - size/2) + 'px;';
    btn.appendChild(circle);
    setTimeout(function() { circle.remove(); }, 600);
  });
});
09 / 31
Shimmer Shine
Pure CSS
A diagonal highlight sweeps across the button surface on hover, like light catching metal.
.btn-shimmer {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(135deg, #7c6cff, #ff6c8a);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.btn-shimmer::after {
  content: '';
  position: absolute;
  top: -50%;
  left: -75%;
  width: 50%;
  height: 200%;
  background: linear-gradient(
    to right,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.35) 50%,
    rgba(255,255,255,0) 100%
  );
  transform: skewX(-20deg);
  transition: left 0.5s;
}
.btn-shimmer:hover::after { left: 130%; }
<button class="btn-shimmer">Premium</button>
10 / 31
Pill Badge
Pure CSS
Fully rounded pill button with a tiny notification count badge in the corner.
.btn-pill {
  padding: 11px 24px;
  border: none;
  border-radius: 99px;
  background: #1f1f2e;
  border: 1px solid rgba(124,108,255,0.3);
  color: #f0eeff;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: border-color 0.2s, background 0.2s;
}
.btn-pill:hover {
  border-color: #7c6cff;
  background: rgba(124,108,255,0.1);
}
.btn-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: #7c6cff;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  border-radius: 99px;
}
<button class="btn-pill">Notifications <span class="btn-badge">4</span></button>
11 / 31
Border Draw
Pure CSS
An SVG-like border traces around the button edge on hover using clip-path or pseudo-element trick.
.btn-border-draw {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: #111118;
  color: #f0eeff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
}
.btn-border-draw::before,
.btn-border-draw::after {
  content: '';
  position: absolute;
  border-radius: 8px;
  inset: 0;
  border: 2px solid transparent;
  transition: border-color 0s;
}
.btn-border-draw::before {
  border-top-color: #7c6cff;
  border-right-color: #7c6cff;
  transition: border-top-color 0.15s, border-right-color 0.15s 0.15s;
}
.btn-border-draw:hover::before {
  border-top-color: #7c6cff;
  border-right-color: #7c6cff;
}
.btn-border-draw::after {
  border-bottom-color: #7c6cff;
  border-left-color: #7c6cff;
  transition: border-bottom-color 0.15s 0.3s, border-left-color 0.15s 0.45s;
}
.btn-border-draw:hover::after {
  border-bottom-color: #7c6cff;
  border-left-color: #7c6cff;
}
<button class="btn-border-draw">Hover Me</button>
12 / 31
Split Color
Pure CSS
The button is split diagonally — one half flips to reveal a contrasting background on hover.
.btn-split {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(135deg, #7c6cff 50%, #ff6c8a 50%);
  background-size: 300% 100%;
  background-position: right;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background-position 0.4s ease;
}
.btn-split:hover { background-position: left; }
<button class="btn-split">Discover</button>
13 / 31
Ghost Invert
Pure CSS
Transparent ghost button that inverts — solid background, white text — on hover.
.btn-ghost-invert {
  padding: 12px 28px;
  border: 2px solid #f0eeff;
  border-radius: 8px;
  background: transparent;
  color: #f0eeff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.25s, color 0.25s;
}
.btn-ghost-invert:hover {
  background: #f0eeff;
  color: #111118;
}
<button class="btn-ghost-invert">Sign Up</button>
14 / 31
Magnetic Lift
Pure CSS
Button lifts with a growing shadow on hover, creating a magnetic floating effect.
.btn-lift {
  padding: 12px 28px;
  border: none;
  border-radius: 10px;
  background: #7c6cff;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(124,108,255,0.3);
  transition: transform 0.2s, box-shadow 0.2s;
}
.btn-lift:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 28px rgba(124,108,255,0.45);
}
.btn-lift:active {
  transform: translateY(0);
  box-shadow: 0 4px 14px rgba(124,108,255,0.3);
}
<button class="btn-lift">Launch</button>
15 / 31
Typewriter
Pure CSS
Button label is revealed character by character with a CSS typewriter animation on page load.
.btn-typewriter {
  padding: 12px 28px;
  border: 1px solid rgba(124,108,255,0.4);
  border-radius: 8px;
  background: #111118;
  color: #7c6cff;
  font-size: 14px;
  font-family: monospace;
  font-weight: 600;
  cursor: pointer;
}
.btn-type-text {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  border-right: 2px solid #7c6cff;
  width: 0;
  animation: btype 2s steps(12, end) forwards, bcaret 0.7s step-end infinite;
}
@keyframes btype  { to { width: 7.5em; } }
@keyframes bcaret { 0%,100% { border-color: transparent; } 50% { border-color: #7c6cff; } }
<button class="btn-typewriter"><span class="btn-type-text">Hello World_</span></button>
16 / 31
Rainbow Border
Pure CSS
An animated conic-gradient rotates around the button border, cycling through the full spectrum.
.btn-rainbow {
  padding: 13px 30px;
  border: none;
  border-radius: 10px;
  background: #111118;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  position: relative;
  z-index: 0;
}
.btn-rainbow::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 12px;
  background: conic-gradient(
    #7c6cff, #ff6c8a, #f5a623, #2ecc8a, #06b6d4, #7c6cff
  );
  z-index: -1;
  animation: rbspin 3s linear infinite;
}
.btn-rainbow::after {
  content: '';
  position: absolute;
  inset: 2px;
  border-radius: 9px;
  background: #111118;
  z-index: -1;
}
@keyframes rbspin { to { transform: rotate(360deg); } }
<button class="btn-rainbow">Upgrade</button>
17 / 31
Soft Neumorphic
Pure CSS
Neumorphic inset/outset shadow creates a soft extruded button on a neutral background.
.btn-neuro {
  padding: 13px 30px;
  border: none;
  border-radius: 12px;
  background: #1e1e2e;
  color: #a78bfa;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  box-shadow:
    6px 6px 12px rgba(0,0,0,0.45),
    -4px -4px 10px rgba(255,255,255,0.04);
  transition: box-shadow 0.15s, transform 0.15s;
}
.btn-neuro:hover {
  box-shadow:
    8px 8px 16px rgba(0,0,0,0.55),
    -5px -5px 12px rgba(255,255,255,0.05);
  transform: translateY(-1px);
}
.btn-neuro:active {
  box-shadow:
    inset 4px 4px 8px rgba(0,0,0,0.5),
    inset -3px -3px 6px rgba(255,255,255,0.03);
  transform: translateY(0);
}
<button class="btn-neuro">Settings</button>
18 / 31
Glitch Text
Pure CSS
The button label glitches with layered pseudo-element offsets and a colour channel shift on hover.
.btn-glitch {
  padding: 12px 28px;
  border: 2px solid #ff6c8a;
  border-radius: 6px;
  background: transparent;
  color: #ff6c8a;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.12em;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.btn-glitch::before,
.btn-glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
}
.btn-glitch::before {
  color: #7c6cff;
  clip-path: polygon(0 0, 100% 0, 100% 45%, 0 45%);
}
.btn-glitch::after {
  color: #2ecc8a;
  clip-path: polygon(0 55%, 100% 55%, 100% 100%, 0 100%);
}
.btn-glitch:hover::before {
  opacity: 1;
  animation: glitch-t 0.3s steps(2) infinite;
}
.btn-glitch:hover::after {
  opacity: 1;
  animation: glitch-b 0.3s steps(2) infinite;
}
@keyframes glitch-t {
  0%   { transform: translateX(-3px); }
  100% { transform: translateX(3px);  }
}
@keyframes glitch-b {
  0%   { transform: translateX(3px);  }
  100% { transform: translateX(-3px); }
}
<button class="btn-glitch" data-text="GLITCH">GLITCH</button>
19 / 31
Loading State
CSS + JS
Button shows a spinning dot loader replacing the label when clicked — no JS framework needed.
.btn-loading {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: #7c6cff;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  min-width: 120px;
  position: relative;
  transition: opacity 0.2s;
}
.btn-loading.is-loading { color: transparent; pointer-events: none; }
.btn-loading.is-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 18px;
  height: 18px;
  border: 2px solid rgba(255,255,255,0.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: btn-spin 0.7s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
<button class="btn-loading" id="btnLoad">Submit</button>
var btnLoad = document.getElementById('btnLoad');
if (btnLoad) {
  btnLoad.addEventListener('click', function() {
    btnLoad.classList.add('is-loading');
    setTimeout(function() { btnLoad.classList.remove('is-loading'); }, 2000);
  });
}
20 / 31
Heartbeat Scale
Pure CSS
The button pulses with a heartbeat scale rhythm — attention-grabbing for CTAs.
.btn-heartbeat {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: #ff6c8a;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  animation: hb-beat 1.3s ease-in-out infinite;
}
@keyframes hb-beat {
  0%,100% { transform: scale(1);    box-shadow: 0 4px 18px rgba(255,108,138,0.3); }
  14%      { transform: scale(1.05); box-shadow: 0 6px 24px rgba(255,108,138,0.5); }
  28%      { transform: scale(1);    box-shadow: 0 4px 18px rgba(255,108,138,0.3); }
  42%      { transform: scale(1.04); box-shadow: 0 5px 20px rgba(255,108,138,0.45); }
}
<button class="btn-heartbeat">Join Now</button>
21 / 31
Underline Reveal
Pure CSS
A slim accent underline grows from the centre outward on hover — minimal and elegant.
.btn-underline {
  padding: 12px 4px;
  border: none;
  background: transparent;
  color: #f0eeff;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
}
.btn-underline::after {
  content: '';
  position: absolute;
  bottom: 4px;
  left: 50%;
  width: 0;
  height: 2px;
  background: #7c6cff;
  border-radius: 2px;
  transition: width 0.3s ease, left 0.3s ease;
}
.btn-underline:hover::after {
  width: 100%;
  left: 0;
}
<button class="btn-underline">Learn CSS</button>
22 / 31
Stagger Dots
Pure CSS
Three dots inside the button bounce in a staggered sequence — great for a "more" or "pending" state.
.btn-dots {
  padding: 14px 28px;
  border: none;
  border-radius: 8px;
  background: #1f1f2e;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.btn-dots span {
  display: block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #7c6cff;
  animation: sdot 1s ease-in-out infinite;
}
.btn-dots span:nth-child(2) { animation-delay: 0.15s; background: #a78bfa; }
.btn-dots span:nth-child(3) { animation-delay: 0.3s;  background: #c4b5fd; }
@keyframes sdot {
  0%,100% { transform: translateY(0); }
  40%      { transform: translateY(-6px); }
}
<button class="btn-dots"><span></span><span></span><span></span></button>
23 / 31
Cut Corner
Pure CSS
A sci-fi style button with a clipped corner using clip-path, paired with a neon accent.
.btn-cut {
  padding: 13px 30px;
  border: none;
  background: rgba(124,108,255,0.15);
  border: 1px solid rgba(124,108,255,0.4);
  color: #a78bfa;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
  cursor: pointer;
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px));
  transition: background 0.2s, color 0.2s;
}
.btn-cut:hover {
  background: rgba(124,108,255,0.3);
  color: #fff;
}
<button class="btn-cut">Execute</button>
24 / 31
Shake Attention
Pure CSS
A short horizontal shake animation fires on hover to demand attention for critical actions.
.btn-shake {
  padding: 12px 28px;
  border: 2px solid #ff6c8a;
  border-radius: 8px;
  background: transparent;
  color: #ff6c8a;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.btn-shake:hover {
  animation: btn-shk 0.4s ease;
}
@keyframes btn-shk {
  0%,100% { transform: translateX(0); }
  20%,60% { transform: translateX(-5px); }
  40%,80% { transform: translateX(5px); }
}
<button class="btn-shake">Delete</button>
25 / 31
Dual Tone
Pure CSS
Icon sits in a differently-coloured left segment divided by a clean rule inside the button.
.btn-dual {
  padding: 0;
  border: none;
  border-radius: 10px;
  background: #7c6cff;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: stretch;
  overflow: hidden;
  transition: filter 0.2s;
}
.btn-dual:hover { filter: brightness(1.12); }
.btn-dual-icon {
  padding: 12px 14px;
  background: rgba(0,0,0,0.2);
  display: flex;
  align-items: center;
  font-size: 16px;
}
.btn-dual-label {
  padding: 12px 20px;
  display: flex;
  align-items: center;
}
<button class="btn-dual"><span class="btn-dual-icon">★</span><span class="btn-dual-label">Star</span></button>
26 / 31
Gradient Rotate
Pure CSS
The gradient angle rotates continuously, giving the button a living, ever-shifting colour flow.
.btn-grad-rot {
  padding: 12px 28px;
  border: none;
  border-radius: 10px;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  background: linear-gradient(var(--a, 135deg), #7c6cff, #ff6c8a, #f5a623);
  background-size: 200% 200%;
  animation: grad-spin 3s linear infinite;
}
@keyframes grad-spin {
  0%   { background-position: 0% 50%;   }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%;   }
}
<button class="btn-grad-rot">Animate</button>
27 / 31
Scale Bounce
Pure CSS
The button springs back with an overshoot using a cubic-bezier spring curve on mouseenter.
.btn-spring {
  padding: 12px 28px;
  border: none;
  border-radius: 8px;
  background: #2ecc8a;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.btn-spring:hover { transform: scale(1.1); }
.btn-spring:active { transform: scale(0.96); }
<button class="btn-spring">Bounce</button>
28 / 31
Frosted Icon
Pure CSS
A glass-morphism button with a leading SVG icon and a translucent tinted background.
.btn-frosted {
  padding: 11px 22px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 10px;
  background: rgba(124,108,255,0.15);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #f0eeff;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background 0.2s, border-color 0.2s;
}
.btn-frosted:hover {
  background: rgba(124,108,255,0.28);
  border-color: rgba(124,108,255,0.5);
}
<button class="btn-frosted"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 5v14M5 12l7 7 7-7"/></svg>Download</button>
29 / 31
Spotlight Hover
CSS + JS
A radial light follows the cursor across the button surface using a CSS custom property updated by JS.
.btn-spotlight {
  padding: 12px 28px;
  border: 1px solid rgba(124,108,255,0.3);
  border-radius: 10px;
  background: #111118;
  color: #f0eeff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.btn-spotlight::before {
  content: '';
  position: absolute;
  width: 120px; height: 120px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(124,108,255,0.25) 0%, transparent 70%);
  transform: translate(var(--x,-60px), var(--y,-60px));
  pointer-events: none;
  transition: transform 0.05s;
}
<button class="btn-spotlight">Hover Me</button>
document.querySelectorAll('.btn-spotlight').forEach(function(btn) {
  btn.addEventListener('mousemove', function(e) {
    var rect = btn.getBoundingClientRect();
    btn.style.setProperty('--spot-x', (e.clientX - rect.left - 60) + 'px');
    btn.style.setProperty('--spot-y', (e.clientY - rect.top  - 60) + 'px');
  });
});
30 / 31
Count Up
CSS + JS
A number increments inside the button on each click using a CSS counter with minimal JS.
.btn-count {
  padding: 11px 22px;
  border: 1px solid rgba(124,108,255,0.35);
  border-radius: 8px;
  background: #1a1a28;
  color: #f0eeff;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: border-color 0.2s;
}
.btn-count:hover { border-color: #7c6cff; }
.btn-count-n {
  font-family: monospace;
  font-size: 13px;
  background: rgba(124,108,255,0.15);
  color: #a78bfa;
  padding: 1px 8px;
  border-radius: 99px;
  min-width: 24px;
  text-align: center;
}
<button class="btn-count" id="btnCount">Likes <span class="btn-count-n">0</span></button>
var btnCount = document.getElementById('btnCount');
if (btnCount) {
  var n = 0;
  btnCount.addEventListener('click', function() {
    n++;
    btnCount.querySelector('.btn-count-n').textContent = n;
  });
}
31 / 31
Magnetic Follow
CSS + JS
The button subtly shifts toward the cursor using JS-driven translate, creating a magnetic pull effect.
.btn-magnet {
  padding: 13px 30px;
  border: none;
  border-radius: 10px;
  background: linear-gradient(135deg, #7c6cff, #a78bfa);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  box-shadow: 0 4px 20px rgba(124,108,255,0.35);
}
.btn-magnet:hover {
  box-shadow: 0 8px 30px rgba(124,108,255,0.5);
}
<button class="btn-magnet">Attract</button>
document.querySelectorAll('.btn-magnet').forEach(function(btn) {
  btn.addEventListener('mousemove', function(e) {
    var rect = btn.getBoundingClientRect();
    var x = (e.clientX - rect.left - rect.width  / 2) * 0.3;
    var y = (e.clientY - rect.top  - rect.height / 2) * 0.3;
    btn.style.transform = 'translate(' + x + 'px,' + y + 'px)';
  });
  btn.addEventListener('mouseleave', function() {
    btn.style.transform = '';
  });
});

Related collections