30 CSS Keyframe Animations 16 / 30
CSS Ripple Click Animation Effect
Material Design ripple animations on six button variants, FAB, chip groups and icon buttons using ::after pseudo-element scale + opacity keyframes.
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="kf-16">
<div style="text-align:center">
<div class="kf-16__title">CSS Ripple Click Animations</div>
<div class="kf-16__subtitle">Material Design ripple effect — pure CSS keyframes</div>
</div>
<div class="kf-16__grid">
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--1">🚀 Launch</button>
<span class="kf-16__label">Filled</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--2">♥ Like</button>
<span class="kf-16__label">Filled Pink</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--3">Subscribe</button>
<span class="kf-16__label">Outlined</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--4">Follow</button>
<span class="kf-16__label">Pill Shape</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--5">Deploy →</button>
<span class="kf-16__label">Orange Flat</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--6">✓ Confirm</button>
<span class="kf-16__label">Rounded</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__fab">+</button>
<span class="kf-16__label">FAB</span>
</div>
<div class="kf-16__cell">
<div class="kf-16__chips">
<button class="kf-16__chip">Design</button>
<button class="kf-16__chip">React</button>
<button class="kf-16__chip">CSS</button>
</div>
<span class="kf-16__label">Chips</span>
</div>
<div class="kf-16__cell">
<div class="kf-16__icon-row">
<button class="kf-16__iconbtn">🏠</button>
<button class="kf-16__iconbtn">🔍</button>
<button class="kf-16__iconbtn">⚙️</button>
<button class="kf-16__iconbtn">👤</button>
</div>
<span class="kf-16__label">Icon Buttons</span>
</div>
</div>
</div> <div class="kf-16">
<div style="text-align:center">
<div class="kf-16__title">CSS Ripple Click Animations</div>
<div class="kf-16__subtitle">Material Design ripple effect — pure CSS keyframes</div>
</div>
<div class="kf-16__grid">
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--1">🚀 Launch</button>
<span class="kf-16__label">Filled</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--2">♥ Like</button>
<span class="kf-16__label">Filled Pink</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--3">Subscribe</button>
<span class="kf-16__label">Outlined</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--4">Follow</button>
<span class="kf-16__label">Pill Shape</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--5">Deploy →</button>
<span class="kf-16__label">Orange Flat</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__btn kf-16__btn--6">✓ Confirm</button>
<span class="kf-16__label">Rounded</span>
</div>
<div class="kf-16__cell">
<button class="kf-16__fab">+</button>
<span class="kf-16__label">FAB</span>
</div>
<div class="kf-16__cell">
<div class="kf-16__chips">
<button class="kf-16__chip">Design</button>
<button class="kf-16__chip">React</button>
<button class="kf-16__chip">CSS</button>
</div>
<span class="kf-16__label">Chips</span>
</div>
<div class="kf-16__cell">
<div class="kf-16__icon-row">
<button class="kf-16__iconbtn">🏠</button>
<button class="kf-16__iconbtn">🔍</button>
<button class="kf-16__iconbtn">⚙️</button>
<button class="kf-16__iconbtn">👤</button>
</div>
<span class="kf-16__label">Icon Buttons</span>
</div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
.kf-16,.kf-16 *,.kf-16 *::before,.kf-16 *::after{box-sizing:border-box;margin:0;padding:0}
.kf-16 ::selection{background:#6200ea;color:#fff}
.kf-16{
--bg:#fafafa;
--dp:#6200ea;
--purple:#7c4dff;
--pink:#e91e63;
--teal:#00bcd4;
--orange:#ff6d00;
--green:#00c853;
--ink:#212121;
font-family:'Roboto',sans-serif;
background:var(--bg);
min-height:100vh;
display:flex;flex-direction:column;align-items:center;justify-content:center;
padding:60px 24px;gap:48px;
color:var(--ink);
}
.kf-16__title{font-size:clamp(1.2rem,4vw,1.8rem);font-weight:700;letter-spacing:-.01em}
.kf-16__subtitle{font-size:.88rem;color:#666;margin-top:4px;text-align:center}
.kf-16__grid{display:flex;flex-wrap:wrap;gap:24px;justify-content:center;max-width:800px}
.kf-16__cell{display:flex;flex-direction:column;align-items:center;gap:14px}
.kf-16__label{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:#999}
/* Material ripple base */
.kf-16__btn{
position:relative;overflow:hidden;
border:none;border-radius:4px;
cursor:pointer;
font-family:'Roboto';font-weight:500;font-size:.9rem;letter-spacing:.08em;text-transform:uppercase;
padding:14px 28px;
display:flex;align-items:center;justify-content:center;gap:8px;
}
.kf-16__btn::after{
content:'';
position:absolute;
top:50%;left:50%;
width:0;height:0;
border-radius:50%;
transform:translate(-50%,-50%);
animation:kf-16-ripple 1.4s ease-out infinite;
}
/* Button variants */
.kf-16__btn--1{background:var(--dp);color:#fff;box-shadow:0 3px 6px rgba(98,0,234,.35)}
.kf-16__btn--1::after{background:rgba(255,255,255,.4)}
.kf-16__btn--2{background:var(--pink);color:#fff;box-shadow:0 3px 6px rgba(233,30,99,.35)}
.kf-16__btn--2::after{background:rgba(255,255,255,.35)}
.kf-16__btn--3{background:#fff;color:var(--dp);border:2px solid var(--dp);box-shadow:0 2px 4px rgba(0,0,0,.1)}
.kf-16__btn--3::after{background:rgba(98,0,234,.2)}
.kf-16__btn--4{background:var(--teal);color:#fff;border-radius:50px;box-shadow:0 3px 8px rgba(0,188,212,.35)}
.kf-16__btn--4::after{background:rgba(255,255,255,.35)}
.kf-16__btn--5{background:var(--orange);color:#fff;border-radius:2px;box-shadow:0 4px 8px rgba(255,109,0,.35)}
.kf-16__btn--5::after{background:rgba(255,255,255,.3);animation-delay:.2s}
.kf-16__btn--6{background:var(--green);color:#fff;border-radius:8px;box-shadow:0 3px 6px rgba(0,200,83,.35)}
.kf-16__btn--6::after{background:rgba(255,255,255,.3)}
@keyframes kf-16-ripple{
0%{width:0;height:0;opacity:.8}
100%{width:220px;height:220px;opacity:0}
}
/* FAB ripple */
.kf-16__fab{
width:56px;height:56px;border-radius:50%;
border:none;background:var(--dp);color:#fff;
font-size:1.4rem;cursor:pointer;
position:relative;overflow:hidden;
box-shadow:0 6px 16px rgba(98,0,234,.45);
display:grid;place-items:center;
flex:0 0 56px;
}
.kf-16__fab::after{
content:'';position:absolute;top:50%;left:50%;
width:0;height:0;border-radius:50%;
transform:translate(-50%,-50%);
background:rgba(255,255,255,.4);
animation:kf-16-ripple 1.4s ease-out infinite .3s;
}
/* Chip ripple */
.kf-16__chip{
padding:8px 18px;border-radius:50px;
border:1.5px solid #ddd;background:#fff;
font-size:.85rem;font-weight:500;cursor:pointer;
position:relative;overflow:hidden;
color:var(--ink);
}
.kf-16__chip::after{
content:'';position:absolute;top:50%;left:50%;
width:0;height:0;border-radius:50%;
transform:translate(-50%,-50%);
background:rgba(98,0,234,.12);
animation:kf-16-ripple 1.2s ease-out infinite;
}
.kf-16__chips{display:flex;flex-wrap:wrap;gap:10px;justify-content:center}
.kf-16__chip:nth-child(2)::after{animation-delay:.25s;background:rgba(233,30,99,.12)}
.kf-16__chip:nth-child(3)::after{animation-delay:.5s;background:rgba(0,188,212,.12)}
/* Icon button ripple */
.kf-16__iconbtn{
width:48px;height:48px;border-radius:50%;
border:none;background:transparent;
font-size:1.3rem;cursor:pointer;
position:relative;overflow:hidden;
display:grid;place-items:center;
}
.kf-16__iconbtn::after{
content:'';position:absolute;top:50%;left:50%;
width:0;height:0;border-radius:50%;
transform:translate(-50%,-50%);
background:rgba(0,0,0,.1);
animation:kf-16-ripple 1.2s ease-out infinite;
}
.kf-16__icon-row{display:flex;gap:8px}
.kf-16__iconbtn:nth-child(2)::after{animation-delay:.2s}
.kf-16__iconbtn:nth-child(3)::after{animation-delay:.4s}
.kf-16__iconbtn:nth-child(4)::after{animation-delay:.6s}
@media(max-width:500px){.kf-16__grid{gap:16px}}
@media(prefers-reduced-motion:reduce){.kf-16 *{animation:none!important}} @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
.kf-16,.kf-16 *,.kf-16 *::before,.kf-16 *::after{box-sizing:border-box;margin:0;padding:0}
.kf-16 ::selection{background:#6200ea;color:#fff}
.kf-16{
--bg:#fafafa;
--dp:#6200ea;
--purple:#7c4dff;
--pink:#e91e63;
--teal:#00bcd4;
--orange:#ff6d00;
--green:#00c853;
--ink:#212121;
font-family:'Roboto',sans-serif;
background:var(--bg);
min-height:100vh;
display:flex;flex-direction:column;align-items:center;justify-content:center;
padding:60px 24px;gap:48px;
color:var(--ink);
}
.kf-16__title{font-size:clamp(1.2rem,4vw,1.8rem);font-weight:700;letter-spacing:-.01em}
.kf-16__subtitle{font-size:.88rem;color:#666;margin-top:4px;text-align:center}
.kf-16__grid{display:flex;flex-wrap:wrap;gap:24px;justify-content:center;max-width:800px}
.kf-16__cell{display:flex;flex-direction:column;align-items:center;gap:14px}
.kf-16__label{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:#999}
/* Material ripple base */
.kf-16__btn{
position:relative;overflow:hidden;
border:none;border-radius:4px;
cursor:pointer;
font-family:'Roboto';font-weight:500;font-size:.9rem;letter-spacing:.08em;text-transform:uppercase;
padding:14px 28px;
display:flex;align-items:center;justify-content:center;gap:8px;
}
.kf-16__btn::after{
content:'';
position:absolute;
top:50%;left:50%;
width:0;height:0;
border-radius:50%;
transform:translate(-50%,-50%);
animation:kf-16-ripple 1.4s ease-out infinite;
}
/* Button variants */
.kf-16__btn--1{background:var(--dp);color:#fff;box-shadow:0 3px 6px rgba(98,0,234,.35)}
.kf-16__btn--1::after{background:rgba(255,255,255,.4)}
.kf-16__btn--2{background:var(--pink);color:#fff;box-shadow:0 3px 6px rgba(233,30,99,.35)}
.kf-16__btn--2::after{background:rgba(255,255,255,.35)}
.kf-16__btn--3{background:#fff;color:var(--dp);border:2px solid var(--dp);box-shadow:0 2px 4px rgba(0,0,0,.1)}
.kf-16__btn--3::after{background:rgba(98,0,234,.2)}
.kf-16__btn--4{background:var(--teal);color:#fff;border-radius:50px;box-shadow:0 3px 8px rgba(0,188,212,.35)}
.kf-16__btn--4::after{background:rgba(255,255,255,.35)}
.kf-16__btn--5{background:var(--orange);color:#fff;border-radius:2px;box-shadow:0 4px 8px rgba(255,109,0,.35)}
.kf-16__btn--5::after{background:rgba(255,255,255,.3);animation-delay:.2s}
.kf-16__btn--6{background:var(--green);color:#fff;border-radius:8px;box-shadow:0 3px 6px rgba(0,200,83,.35)}
.kf-16__btn--6::after{background:rgba(255,255,255,.3)}
@keyframes kf-16-ripple{
0%{width:0;height:0;opacity:.8}
100%{width:220px;height:220px;opacity:0}
}
/* FAB ripple */
.kf-16__fab{
width:56px;height:56px;border-radius:50%;
border:none;background:var(--dp);color:#fff;
font-size:1.4rem;cursor:pointer;
position:relative;overflow:hidden;
box-shadow:0 6px 16px rgba(98,0,234,.45);
display:grid;place-items:center;
flex:0 0 56px;
}
.kf-16__fab::after{
content:'';position:absolute;top:50%;left:50%;
width:0;height:0;border-radius:50%;
transform:translate(-50%,-50%);
background:rgba(255,255,255,.4);
animation:kf-16-ripple 1.4s ease-out infinite .3s;
}
/* Chip ripple */
.kf-16__chip{
padding:8px 18px;border-radius:50px;
border:1.5px solid #ddd;background:#fff;
font-size:.85rem;font-weight:500;cursor:pointer;
position:relative;overflow:hidden;
color:var(--ink);
}
.kf-16__chip::after{
content:'';position:absolute;top:50%;left:50%;
width:0;height:0;border-radius:50%;
transform:translate(-50%,-50%);
background:rgba(98,0,234,.12);
animation:kf-16-ripple 1.2s ease-out infinite;
}
.kf-16__chips{display:flex;flex-wrap:wrap;gap:10px;justify-content:center}
.kf-16__chip:nth-child(2)::after{animation-delay:.25s;background:rgba(233,30,99,.12)}
.kf-16__chip:nth-child(3)::after{animation-delay:.5s;background:rgba(0,188,212,.12)}
/* Icon button ripple */
.kf-16__iconbtn{
width:48px;height:48px;border-radius:50%;
border:none;background:transparent;
font-size:1.3rem;cursor:pointer;
position:relative;overflow:hidden;
display:grid;place-items:center;
}
.kf-16__iconbtn::after{
content:'';position:absolute;top:50%;left:50%;
width:0;height:0;border-radius:50%;
transform:translate(-50%,-50%);
background:rgba(0,0,0,.1);
animation:kf-16-ripple 1.2s ease-out infinite;
}
.kf-16__icon-row{display:flex;gap:8px}
.kf-16__iconbtn:nth-child(2)::after{animation-delay:.2s}
.kf-16__iconbtn:nth-child(3)::after{animation-delay:.4s}
.kf-16__iconbtn:nth-child(4)::after{animation-delay:.6s}
@media(max-width:500px){.kf-16__grid{gap:16px}}
@media(prefers-reduced-motion:reduce){.kf-16 *{animation:none!important}}How this works
Every button has position: relative; overflow: hidden and a ::after pseudo-element absolutely positioned at the centre with zero width and height. The shared kf-16-ripple keyframe grows the pseudo to 220px × 220px while fading opacity: .8 → 0, simulating the Material Design ink response radiating from the click point.
Variants differ only in the ripple's background colour (white on filled, semi-transparent purple on outlined) and animation delays (filled at 0s, orange flat at 0.2s) so a row of buttons doesn't pulse in lockstep. Chips and icon buttons use the same pattern with smaller pseudo sizes, while the FAB extends ripple alpha to 0.4 against the dark purple background.
Customize
- Adjust ripple size by editing the
width: 220px; height: 220pxinkf-16-ripple— scale proportionally to button size. - Recolour the ink via
::after { background: rgba(255,255,255,.4) }on each variant. - Slow the ripple by changing
1.4s ease-outto2sfor a more deliberate Material feel. - Match Material spec by replacing the auto-loop with a
:active-triggered animation — see the gotchas note.
Watch out for
- Real Material ripples respond to click position, not the centre — this demo loops automatically for showcase but should be replaced with JS-driven ripples in production.
overflow: hiddenon the button clips both the ripple and any focus ring — use:focus-visiblewith a separatebox-shadowoutline.- The auto-looping animation never stops, costing real frame budget per button — disable when not in viewport or convert to a one-shot interaction.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 60+ | 12+ | 60+ | 60+ |