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.
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
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> <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; }
} @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 });
});
}); 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 });
});
});More from 12 CSS Ripple Effects
CSS Sonar Ping Ripple AnimationCSS Ripple Card Hover EffectCSS Sound Wave Ripple VisualizerCSS Liquid Drop Ripple AnimationCSS Water Ripple Click EffectCSS Pond Ripple Background AnimationCSS Heartbeat Pulse Ripple EffectCSS Ripple Login Form UICSS Aurora Borealis Ripple BackgroundCSS Neon Glow Ripple EffectCSS Ripple Loading Spinner
View the full collection →