22 CSS Transition Effects 13 / 22
Ripple Effect on Click
Material Design ripple: JS inserts a wave span at click coordinates with contained, outlined and text buttons, FABs, chips, list items and cards.
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="wrap">
<h1>CSS Ripple Effect</h1>
<p class="sub">Material Design ripple on click — click any element below to trigger the wave</p>
<span class="sl">Contained buttons</span>
<div class="grid">
<button class="mat-btn mat-contained ripple c-purple"><span>Primary</span></button>
<button class="mat-btn mat-contained ripple c-pink"><span>Secondary</span></button>
<button class="mat-btn mat-contained ripple c-teal"><span>Success</span></button>
<button class="mat-btn mat-contained ripple c-orange"><span>Warning</span></button>
</div>
<span class="sl">Outlined + text buttons</span>
<div class="grid">
<button class="mat-btn mat-outlined ripple c-purple"><span>Outlined</span></button>
<button class="mat-btn mat-outlined ripple c-pink"><span>Outlined</span></button>
<button class="mat-btn mat-text ripple c-teal"><span>Text button</span></button>
<button class="mat-btn mat-text ripple c-orange"><span>Text button</span></button>
</div>
<span class="sl">FABs + chips</span>
<div style="display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap;margin-bottom:48px">
<button class="mat-fab ripple c-purple">✚</button>
<button class="mat-fab ripple c-pink">♥</button>
<button class="mat-fab ripple c-teal">↑</button>
<button class="mat-fab ripple c-orange">✎</button>
</div>
<span class="sl">Filter chips</span>
<div class="mat-chips" id="chips">
<div class="mat-chip ripple selected c-purple" data-chip>All</div>
<div class="mat-chip ripple" data-chip>Design</div>
<div class="mat-chip ripple" data-chip>Development</div>
<div class="mat-chip ripple" data-chip>Marketing</div>
<div class="mat-chip ripple" data-chip>Research</div>
<div class="mat-chip ripple" data-chip>Strategy</div>
</div>
<span class="sl">List items</span>
<div class="mat-list">
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#e8eaf6">📧</div><div class="mat-list-text"><div class="mat-list-title">Inbox</div><div class="mat-list-sub">3 unread messages</div></div></div>
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#fce4ec">⭐</div><div class="mat-list-text"><div class="mat-list-title">Starred</div><div class="mat-list-sub">12 starred items</div></div></div>
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#e0f7fa">📤</div><div class="mat-list-text"><div class="mat-list-title">Sent</div><div class="mat-list-sub">All sent messages</div></div></div>
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#fff3e0">🗑️</div><div class="mat-list-text"><div class="mat-list-title">Trash</div><div class="mat-list-sub">Auto-deleted in 30 days</div></div></div>
</div>
<span class="sl">Cards</span>
<div class="grid-2">
<div class="mat-card ripple"><h3>📊 Analytics Report</h3><p>Monthly performance summary across all tracked campaigns and organic channels.</p></div>
<div class="mat-card ripple"><h3>🚀 Deploy Pipeline</h3><p>Automated CI/CD with staging, canary release and one-click rollback capability.</p></div>
</div>
</div> <div class="wrap">
<h1>CSS Ripple Effect</h1>
<p class="sub">Material Design ripple on click — click any element below to trigger the wave</p>
<span class="sl">Contained buttons</span>
<div class="grid">
<button class="mat-btn mat-contained ripple c-purple"><span>Primary</span></button>
<button class="mat-btn mat-contained ripple c-pink"><span>Secondary</span></button>
<button class="mat-btn mat-contained ripple c-teal"><span>Success</span></button>
<button class="mat-btn mat-contained ripple c-orange"><span>Warning</span></button>
</div>
<span class="sl">Outlined + text buttons</span>
<div class="grid">
<button class="mat-btn mat-outlined ripple c-purple"><span>Outlined</span></button>
<button class="mat-btn mat-outlined ripple c-pink"><span>Outlined</span></button>
<button class="mat-btn mat-text ripple c-teal"><span>Text button</span></button>
<button class="mat-btn mat-text ripple c-orange"><span>Text button</span></button>
</div>
<span class="sl">FABs + chips</span>
<div style="display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap;margin-bottom:48px">
<button class="mat-fab ripple c-purple">✚</button>
<button class="mat-fab ripple c-pink">♥</button>
<button class="mat-fab ripple c-teal">↑</button>
<button class="mat-fab ripple c-orange">✎</button>
</div>
<span class="sl">Filter chips</span>
<div class="mat-chips" id="chips">
<div class="mat-chip ripple selected c-purple" data-chip>All</div>
<div class="mat-chip ripple" data-chip>Design</div>
<div class="mat-chip ripple" data-chip>Development</div>
<div class="mat-chip ripple" data-chip>Marketing</div>
<div class="mat-chip ripple" data-chip>Research</div>
<div class="mat-chip ripple" data-chip>Strategy</div>
</div>
<span class="sl">List items</span>
<div class="mat-list">
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#e8eaf6">📧</div><div class="mat-list-text"><div class="mat-list-title">Inbox</div><div class="mat-list-sub">3 unread messages</div></div></div>
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#fce4ec">⭐</div><div class="mat-list-text"><div class="mat-list-title">Starred</div><div class="mat-list-sub">12 starred items</div></div></div>
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#e0f7fa">📤</div><div class="mat-list-text"><div class="mat-list-title">Sent</div><div class="mat-list-sub">All sent messages</div></div></div>
<div class="mat-list-item ripple"><div class="mat-list-icon" style="--ic:#fff3e0">🗑️</div><div class="mat-list-text"><div class="mat-list-title">Trash</div><div class="mat-list-sub">Auto-deleted in 30 days</div></div></div>
</div>
<span class="sl">Cards</span>
<div class="grid-2">
<div class="mat-card ripple"><h3>📊 Analytics Report</h3><p>Monthly performance summary across all tracked campaigns and organic channels.</p></div>
<div class="mat-card ripple"><h3>🚀 Deploy Pipeline</h3><p>Automated CI/CD with staging, canary release and one-click rollback capability.</p></div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Roboto',sans-serif;background:#fafafa;color:#212121;min-height:100vh;padding:60px 24px}
.wrap{max-width:1000px;margin:0 auto}
h1{font-size:clamp(2rem,5vw,3rem);font-weight:700;text-align:center;margin-bottom:8px;letter-spacing:-.02em}
.sub{text-align:center;color:#757575;margin-bottom:56px}
.sl{font-size:.65rem;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:#9e9e9e;margin-bottom:16px;display:block}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px;margin-bottom:48px}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:48px}
@media(max-width:600px){.grid-2{grid-template-columns:1fr}}
/* RIPPLE CORE */
.ripple{position:relative;overflow:hidden;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent}
.ripple-wave{position:absolute;border-radius:50%;transform:scale(0);animation:trn13-ripple .6s cubic-bezier(.4,0,.2,1) forwards;pointer-events:none}
@keyframes trn13-ripple{to{transform:scale(4);opacity:0}}
/* Material Buttons */
.mat-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:'Roboto';font-weight:500;font-size:.875rem;letter-spacing:.089em;text-transform:uppercase;padding:0 24px;height:36px;border:none;border-radius:4px;cursor:pointer;position:relative;overflow:hidden;transition:box-shadow .28s cubic-bezier(.4,0,.2,1)}
.mat-btn span{position:relative;z-index:1}
/* Contained */
.mat-contained{background:var(--c,#6200ea);color:#fff;box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}
.mat-contained:hover{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}
.mat-contained .ripple-wave{background:rgba(255,255,255,.3)}
/* Outlined */
.mat-outlined{background:transparent;color:var(--c,#6200ea);border:1px solid currentColor}
.mat-outlined .ripple-wave{background:rgba(var(--crgb,98,0,234),.12)}
/* Text */
.mat-text{background:transparent;color:var(--c,#6200ea)}
.mat-text .ripple-wave{background:rgba(var(--crgb,98,0,234),.12)}
/* FAB */
.mat-fab{width:56px;height:56px;border-radius:50%;background:var(--c,#6200ea);color:#fff;font-size:1.2rem;border:none;cursor:pointer;position:relative;overflow:hidden;display:grid;place-items:center;box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);transition:box-shadow .28s}
.mat-fab:hover{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}
.mat-fab .ripple-wave{background:rgba(255,255,255,.3)}
/* Card ripple */
.mat-card{background:#fff;border-radius:4px;padding:24px;cursor:pointer;position:relative;overflow:hidden;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);transition:box-shadow .28s}
.mat-card:hover{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}
.mat-card .ripple-wave{background:rgba(0,0,0,.08)}
.mat-card h3{font-size:1rem;font-weight:500;margin-bottom:8px;position:relative;z-index:1}
.mat-card p{font-size:.875rem;color:#757575;line-height:1.5;position:relative;z-index:1}
/* List ripple */
.mat-list{background:#fff;border-radius:4px;overflow:hidden;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);margin-bottom:48px}
.mat-list-item{display:flex;align-items:center;gap:16px;padding:16px;cursor:pointer;position:relative;overflow:hidden;border-bottom:1px solid rgba(0,0,0,.12);transition:background .15s}
.mat-list-item:last-child{border:0}
.mat-list-item:hover{background:rgba(0,0,0,.04)}
.mat-list-item .ripple-wave{background:rgba(0,0,0,.08)}
.mat-list-icon{width:40px;height:40px;border-radius:50%;background:var(--ic,#e8eaf6);display:grid;place-items:center;font-size:1.1rem;flex:0 0 40px;position:relative;z-index:1}
.mat-list-text{position:relative;z-index:1}
.mat-list-title{font-size:.875rem;font-weight:500}
.mat-list-sub{font-size:.75rem;color:#757575;margin-top:2px}
/* Chip ripple */
.mat-chips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:48px}
.mat-chip{display:inline-flex;align-items:center;gap:6px;padding:0 12px;height:32px;border-radius:16px;background:#e0e0e0;font-size:.875rem;font-weight:500;cursor:pointer;position:relative;overflow:hidden;transition:background .2s}
.mat-chip:hover,.mat-chip.selected{background:#bdbdbd}
.mat-chip.selected{background:var(--c,#6200ea);color:#fff}
.mat-chip .ripple-wave{background:rgba(0,0,0,.1)}
.mat-chip.selected .ripple-wave{background:rgba(255,255,255,.3)}
/* colours */
.c-purple{--c:#6200ea;--crgb:98,0,234}
.c-pink{--c:#e91e63;--crgb:233,30,99}
.c-teal{--c:#009688;--crgb:0,150,136}
.c-orange{--c:#ff5722;--crgb:255,87,34}
.c-indigo{--c:#3f51b5;--crgb:63,81,181}
@media (prefers-reduced-motion:reduce){.ripple-wave{animation:none !important}} @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Roboto',sans-serif;background:#fafafa;color:#212121;min-height:100vh;padding:60px 24px}
.wrap{max-width:1000px;margin:0 auto}
h1{font-size:clamp(2rem,5vw,3rem);font-weight:700;text-align:center;margin-bottom:8px;letter-spacing:-.02em}
.sub{text-align:center;color:#757575;margin-bottom:56px}
.sl{font-size:.65rem;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:#9e9e9e;margin-bottom:16px;display:block}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px;margin-bottom:48px}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:48px}
@media(max-width:600px){.grid-2{grid-template-columns:1fr}}
/* RIPPLE CORE */
.ripple{position:relative;overflow:hidden;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent}
.ripple-wave{position:absolute;border-radius:50%;transform:scale(0);animation:trn13-ripple .6s cubic-bezier(.4,0,.2,1) forwards;pointer-events:none}
@keyframes trn13-ripple{to{transform:scale(4);opacity:0}}
/* Material Buttons */
.mat-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:'Roboto';font-weight:500;font-size:.875rem;letter-spacing:.089em;text-transform:uppercase;padding:0 24px;height:36px;border:none;border-radius:4px;cursor:pointer;position:relative;overflow:hidden;transition:box-shadow .28s cubic-bezier(.4,0,.2,1)}
.mat-btn span{position:relative;z-index:1}
/* Contained */
.mat-contained{background:var(--c,#6200ea);color:#fff;box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}
.mat-contained:hover{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}
.mat-contained .ripple-wave{background:rgba(255,255,255,.3)}
/* Outlined */
.mat-outlined{background:transparent;color:var(--c,#6200ea);border:1px solid currentColor}
.mat-outlined .ripple-wave{background:rgba(var(--crgb,98,0,234),.12)}
/* Text */
.mat-text{background:transparent;color:var(--c,#6200ea)}
.mat-text .ripple-wave{background:rgba(var(--crgb,98,0,234),.12)}
/* FAB */
.mat-fab{width:56px;height:56px;border-radius:50%;background:var(--c,#6200ea);color:#fff;font-size:1.2rem;border:none;cursor:pointer;position:relative;overflow:hidden;display:grid;place-items:center;box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);transition:box-shadow .28s}
.mat-fab:hover{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}
.mat-fab .ripple-wave{background:rgba(255,255,255,.3)}
/* Card ripple */
.mat-card{background:#fff;border-radius:4px;padding:24px;cursor:pointer;position:relative;overflow:hidden;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);transition:box-shadow .28s}
.mat-card:hover{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}
.mat-card .ripple-wave{background:rgba(0,0,0,.08)}
.mat-card h3{font-size:1rem;font-weight:500;margin-bottom:8px;position:relative;z-index:1}
.mat-card p{font-size:.875rem;color:#757575;line-height:1.5;position:relative;z-index:1}
/* List ripple */
.mat-list{background:#fff;border-radius:4px;overflow:hidden;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);margin-bottom:48px}
.mat-list-item{display:flex;align-items:center;gap:16px;padding:16px;cursor:pointer;position:relative;overflow:hidden;border-bottom:1px solid rgba(0,0,0,.12);transition:background .15s}
.mat-list-item:last-child{border:0}
.mat-list-item:hover{background:rgba(0,0,0,.04)}
.mat-list-item .ripple-wave{background:rgba(0,0,0,.08)}
.mat-list-icon{width:40px;height:40px;border-radius:50%;background:var(--ic,#e8eaf6);display:grid;place-items:center;font-size:1.1rem;flex:0 0 40px;position:relative;z-index:1}
.mat-list-text{position:relative;z-index:1}
.mat-list-title{font-size:.875rem;font-weight:500}
.mat-list-sub{font-size:.75rem;color:#757575;margin-top:2px}
/* Chip ripple */
.mat-chips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:48px}
.mat-chip{display:inline-flex;align-items:center;gap:6px;padding:0 12px;height:32px;border-radius:16px;background:#e0e0e0;font-size:.875rem;font-weight:500;cursor:pointer;position:relative;overflow:hidden;transition:background .2s}
.mat-chip:hover,.mat-chip.selected{background:#bdbdbd}
.mat-chip.selected{background:var(--c,#6200ea);color:#fff}
.mat-chip .ripple-wave{background:rgba(0,0,0,.1)}
.mat-chip.selected .ripple-wave{background:rgba(255,255,255,.3)}
/* colours */
.c-purple{--c:#6200ea;--crgb:98,0,234}
.c-pink{--c:#e91e63;--crgb:233,30,99}
.c-teal{--c:#009688;--crgb:0,150,136}
.c-orange{--c:#ff5722;--crgb:255,87,34}
.c-indigo{--c:#3f51b5;--crgb:63,81,181}
@media (prefers-reduced-motion:reduce){.ripple-wave{animation:none !important}}// Ripple on click
document.querySelectorAll('.ripple').forEach(el => {
el.addEventListener('click', e => {
const rect = el.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const size = Math.max(rect.width, rect.height) * 2;
const wave = document.createElement('span');
wave.className = 'ripple-wave';
wave.style.cssText = `width:${size}px;height:${size}px;left:${x - size/2}px;top:${y - size/2}px`;
el.appendChild(wave);
wave.addEventListener('animationend', () => wave.remove());
});
});
// Chip toggle
document.getElementById('chips').addEventListener('click', e => {
const chip = e.target.closest('[data-chip]');
if(!chip) return;
chip.classList.toggle('selected');
}); // Ripple on click
document.querySelectorAll('.ripple').forEach(el => {
el.addEventListener('click', e => {
const rect = el.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const size = Math.max(rect.width, rect.height) * 2;
const wave = document.createElement('span');
wave.className = 'ripple-wave';
wave.style.cssText = `width:${size}px;height:${size}px;left:${x - size/2}px;top:${y - size/2}px`;
el.appendChild(wave);
wave.addEventListener('animationend', () => wave.remove());
});
});
// Chip toggle
document.getElementById('chips').addEventListener('click', e => {
const chip = e.target.closest('[data-chip]');
if(!chip) return;
chip.classList.toggle('selected');
});More from 22 CSS Transition Effects
Slide-In Animation on ScrollFade In Fade Out TransitionLoading Skeleton TransitionModal Open Close TransitionPage Transition EffectNumber Counter AnimationCard Tilt 3D HoverStaggered List AnimationCursor Trail EffectMagnetic Button EffectSplit Text Reveal TransitionProgress Bar Animation
View the full collection →