12 CSS Ripple Effects 02 / 12

CSS Ripple Button Click Animation

A full Material-style ink-ripple button kit in eight color variants — fire, ocean, emerald, violet, gold, rose, ghost and dark-surface — each with a radial ink span injected at the click coordinate that scales to fill and fades.

CSS + JS MIT licensed
Live Demo Open in tab

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="rpl-02">
  <div class="rpl-02__header">
    <h1>Ripple Button Click Animation</h1>
    <p>Material-style ink ripple on every button press — pure CSS + minimal JS</p>
  </div>

  <div class="rpl-02__grid">
    <button class="rpl-02__btn rpl-02__btn--fire">
      <span class="rpl-02__icon">🔥</span> Get Started
    </button>
    <button class="rpl-02__btn rpl-02__btn--ocean">
      <span class="rpl-02__icon">🌊</span> Dive In
    </button>
    <button class="rpl-02__btn rpl-02__btn--emerald">
      <span class="rpl-02__icon">✓</span> Confirm
    </button>
    <button class="rpl-02__btn rpl-02__btn--violet">
      <span class="rpl-02__icon">✦</span> Upgrade
    </button>
    <button class="rpl-02__btn rpl-02__btn--gold">
      <span class="rpl-02__icon">★</span> Premium
    </button>
    <button class="rpl-02__btn rpl-02__btn--rose">
      <span class="rpl-02__icon">♥</span> Save
    </button>
    <button class="rpl-02__btn rpl-02__btn--ghost">
      Ghost Style
    </button>
    <button class="rpl-02__btn rpl-02__btn--dark">
      Dark Surface
    </button>
  </div>

  <div class="rpl-02__code">
    <h3>How it works</h3>
    <pre><span class="cm">/* On click, inject a positioned ink div */</span>
<span class="kw">.btn</span> { position: relative; overflow: hidden; }

<span class="kw">.ink</span> {
  position: absolute; border-radius: 50%;
  animation: <span class="str">ink-expand</span> 0.6s linear forwards;
}
@keyframes <span class="str">ink-expand</span> {
  to { transform: scale(4); opacity: 0; }
}</pre>
  </div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

.rpl-02, .rpl-02 *, .rpl-02 *::before, .rpl-02 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.rpl-02 ::selection { background: #ff6b35; color: #fff; }

.rpl-02 {
  --bg: #0f0f13;
  --surface: #1a1a23;
  --border: rgba(255,255,255,0.08);
  --text: #f0f0f5;
  --muted: rgba(240,240,245,0.45);
  font-family: 'Inter', sans-serif;
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 56px;
  padding: 60px 24px;
  color: var(--text);
}

.rpl-02__header {
  text-align: center;
}
.rpl-02__header h1 {
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
}
.rpl-02__header p {
  margin-top: 10px;
  color: var(--muted);
  font-weight: 300;
  font-size: 0.95rem;
}

.rpl-02__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  width: min(860px, 100%);
}

/* The core ripple button */
.rpl-02__btn {
  position: relative;
  overflow: hidden;
  border: none;
  cursor: pointer;
  font-family: 'Inter';
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  padding: 18px 32px;
  border-radius: 12px;
  color: #fff;
  transition: transform 0.15s, filter 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 60px;
}
.rpl-02__btn:hover { transform: translateY(-2px); filter: brightness(1.08); }
.rpl-02__btn:active { transform: translateY(1px); filter: brightness(0.95); }

/* Ripple ink */
.rpl-02__btn .ink {
  position: absolute;
  border-radius: 50%;
  transform: scale(0);
  pointer-events: none;
  animation: rpl-02-ink 0.6s linear forwards;
}
@keyframes rpl-02-ink {
  to { transform: scale(4); opacity: 0; }
}

/* Variant colors */
.rpl-02__btn--fire {
  background: linear-gradient(135deg, #ff4500, #ff6b35);
  box-shadow: 0 8px 32px rgba(255,69,0,0.35);
}
.rpl-02__btn--fire .ink { background: rgba(255,200,150,0.45); }

.rpl-02__btn--ocean {
  background: linear-gradient(135deg, #0077b6, #00b4d8);
  box-shadow: 0 8px 32px rgba(0,119,182,0.35);
}
.rpl-02__btn--ocean .ink { background: rgba(160,230,255,0.4); }

.rpl-02__btn--emerald {
  background: linear-gradient(135deg, #065f46, #10b981);
  box-shadow: 0 8px 32px rgba(16,185,129,0.3);
}
.rpl-02__btn--emerald .ink { background: rgba(160,255,210,0.4); }

.rpl-02__btn--violet {
  background: linear-gradient(135deg, #5b21b6, #8b5cf6);
  box-shadow: 0 8px 32px rgba(139,92,246,0.35);
}
.rpl-02__btn--violet .ink { background: rgba(220,190,255,0.4); }

.rpl-02__btn--gold {
  background: linear-gradient(135deg, #92400e, #f59e0b);
  box-shadow: 0 8px 32px rgba(245,158,11,0.3);
}
.rpl-02__btn--gold .ink { background: rgba(255,245,180,0.45); }

.rpl-02__btn--rose {
  background: linear-gradient(135deg, #9f1239, #fb7185);
  box-shadow: 0 8px 32px rgba(251,113,133,0.35);
}
.rpl-02__btn--rose .ink { background: rgba(255,200,210,0.4); }

/* Outlined ghost variant */
.rpl-02__btn--ghost {
  background: transparent;
  border: 1.5px solid rgba(255,255,255,0.25);
  color: var(--text);
  box-shadow: none;
}
.rpl-02__btn--ghost:hover { border-color: rgba(255,255,255,0.55); background: rgba(255,255,255,0.04); }
.rpl-02__btn--ghost .ink { background: rgba(255,255,255,0.15); }

/* Dark surface variant */
.rpl-02__btn--dark {
  background: var(--surface);
  border: 1.5px solid var(--border);
  color: var(--text);
  box-shadow: 0 4px 16px rgba(0,0,0,0.3);
}
.rpl-02__btn--dark .ink { background: rgba(255,255,255,0.12); }

/* Icon pill */
.rpl-02__icon {
  font-size: 1.1rem;
  line-height: 1;
}

/* Code snippet */
.rpl-02__code {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 24px;
  width: min(860px, 100%);
}
.rpl-02__code h3 {
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}
.rpl-02__code pre {
  font-size: 0.82rem;
  line-height: 1.65;
  color: rgba(240,240,245,0.75);
  font-family: 'Courier New', monospace;
  white-space: pre-wrap;
  word-break: break-word;
}
.rpl-02__code .kw { color: #c084fc; }
.rpl-02__code .str { color: #86efac; }
.rpl-02__code .cm { color: rgba(240,240,245,0.3); font-style: italic; }

@media (prefers-reduced-motion: reduce) {
  .rpl-02__btn .ink { animation: none !important; }
  .rpl-02__btn { transition: none; }
}
document.querySelectorAll('.rpl-02__btn').forEach(btn => {
  btn.addEventListener('click', function(e) {
    const rect = this.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    const size = Math.max(rect.width, rect.height);
    const ink = document.createElement('span');
    ink.className = 'ink';
    ink.style.cssText = `
      left:${x - size/2}px; top:${y - size/2}px;
      width:${size}px; height:${size}px;
    `;
    this.appendChild(ink);
    ink.addEventListener('animationend', () => ink.remove(), { once: true });
  });
});

Search CodeFronts

Loading…