15 / 20
All 20 in 20 CSS Image Hover Effects
- 01CSS Image Hover Zoom In Card
- 02CSS Hover Reveal Text Over Image
- 03E-Commerce Product Image Swap on Hover
- 04CSS Grid Image Blur Overlay Text Hover
- 05CSS Card Slide Up Caption on Hover
- 06CSS Grayscale to Color Image Hover
- 07CSS Image Color Overlay Tint on Hover
- 08Neumorphic Image Card Hover Effect CSS
- 09Glassmorphism Overlay on Image Hover
- 10CSS Glowing Neon Border Image Hover
- 11CSS Image Clip-Path Transition Hover
- 12CSS Image Tilt 3D Perspective Hover
- 13CSS Shining Light Glare Image Hover
- 14CSS Image Split Transition Hover
- 15CSS Image Ripple Animation Hover
- 16Circular Team Profile Avatar Hover CSS
- 17CSS Fullscreen Background Image Hover
- 18CSS Masonry Gallery Zoom Hover
- 19CSS Image Icon Reveal Center Hover
- 20CSS Image Card Flip 3D Animation Hover
CSS Image Ripple Animation Hover
Concentric circle ripples emanate outward from a circular avatar on hover, driven by staggered keyframe animations on sibling span elements.
Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS
ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link
The code
<div class="ih-15">
<div class="ih-15__grid">
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--1">👩🚀</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Dr. Elena Vasquez</p>
<p class="ih-15__role">Mission Architect</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--2">🧙</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Orion Blackwood</p>
<p class="ih-15__role">AI Research Lead</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--3">👩🌾</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Freya Lindqvist</p>
<p class="ih-15__role">Growth Engineer</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
</div>
</div><div class="ih-15">
<div class="ih-15__grid">
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--1">👩🚀</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Dr. Elena Vasquez</p>
<p class="ih-15__role">Mission Architect</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--2">🧙</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Orion Blackwood</p>
<p class="ih-15__role">AI Research Lead</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--3">👩🌾</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Freya Lindqvist</p>
<p class="ih-15__role">Growth Engineer</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
</div>
</div>.ih-15,
.ih-15 *,
.ih-15 *::before,
.ih-15 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-15 ::selection {
background: #2dd4bf;
color: #000;
}
.ih-15 {
--accent: #2dd4bf;
--bg: #060d0d;
--text: #f1f5f9;
--muted: #64748b;
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-15__item {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
cursor: pointer;
}
/* Ripple container — must be position:relative so pseudo rings use absolute */
.ih-15__frame {
position: relative;
width: 140px;
height: 140px;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__avatar {
width: 100px;
height: 100px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 42px;
position: relative;
z-index: 2;
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1);
}
.ih-15__avatar--1 {
background: radial-gradient(circle,#1e3a5f,#0369a1);
}
.ih-15__avatar--2 {
background: radial-gradient(circle,#3b0764,#7e22ce);
}
.ih-15__avatar--3 {
background: radial-gradient(circle,#052e16,#15803d);
}
.ih-15__item:hover .ih-15__avatar {
transform: scale(1.08);
}
/* Three ripple rings using sibling spans — keyframe scales + fades */
.ih-15__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--accent);
opacity: 0;
animation: none;
}
.ih-15__item:hover .ih-15__ring {
animation: ih-15-ripple 1.5s cubic-bezier(0,0.2,0.8,1) infinite;
}
.ih-15__ring:nth-child(2) {
animation-delay: 0s;
}
.ih-15__ring:nth-child(3) {
animation-delay: 0.5s;
}
.ih-15__ring:nth-child(4) {
animation-delay: 1s;
}
@keyframes ih-15-ripple {
0% {
width: 100px;
height: 100px;
opacity: 0.6;
top: calc(50% - 50px);
left: calc(50% - 50px);
}
100% {
width: 140px;
height: 140px;
opacity: 0;
top: calc(50% - 70px);
left: calc(50% - 70px);
}
}
/* Colour the rings per item */
.ih-15__item:nth-child(1) .ih-15__ring {
border-color: #38bdf8;
}
.ih-15__item:nth-child(2) .ih-15__ring {
border-color: #c084fc;
}
.ih-15__item:nth-child(3) .ih-15__ring {
border-color: #4ade80;
}
.ih-15__name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-15__role {
font-size: 11px;
color: var(--muted);
}
.ih-15__socials {
display: flex;
gap: 8px;
margin-top: 4px;
}
.ih-15__social {
width: 26px;
height: 26px;
border-radius: 50%;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.08);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
transition: background 0.2s ease;
}
.ih-15__item:hover .ih-15__social {
background: rgba(255,255,255,0.1);
}
@media (prefers-reduced-motion: reduce) {
.ih-15__ring,
.ih-15__avatar {
animation: none!important;
transition: none;
}
}.ih-15,
.ih-15 *,
.ih-15 *::before,
.ih-15 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-15 ::selection {
background: #2dd4bf;
color: #000;
}
.ih-15 {
--accent: #2dd4bf;
--bg: #060d0d;
--text: #f1f5f9;
--muted: #64748b;
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-15__item {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
cursor: pointer;
}
/* Ripple container — must be position:relative so pseudo rings use absolute */
.ih-15__frame {
position: relative;
width: 140px;
height: 140px;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__avatar {
width: 100px;
height: 100px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 42px;
position: relative;
z-index: 2;
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1);
}
.ih-15__avatar--1 {
background: radial-gradient(circle,#1e3a5f,#0369a1);
}
.ih-15__avatar--2 {
background: radial-gradient(circle,#3b0764,#7e22ce);
}
.ih-15__avatar--3 {
background: radial-gradient(circle,#052e16,#15803d);
}
.ih-15__item:hover .ih-15__avatar {
transform: scale(1.08);
}
/* Three ripple rings using sibling spans — keyframe scales + fades */
.ih-15__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--accent);
opacity: 0;
animation: none;
}
.ih-15__item:hover .ih-15__ring {
animation: ih-15-ripple 1.5s cubic-bezier(0,0.2,0.8,1) infinite;
}
.ih-15__ring:nth-child(2) {
animation-delay: 0s;
}
.ih-15__ring:nth-child(3) {
animation-delay: 0.5s;
}
.ih-15__ring:nth-child(4) {
animation-delay: 1s;
}
@keyframes ih-15-ripple {
0% {
width: 100px;
height: 100px;
opacity: 0.6;
top: calc(50% - 50px);
left: calc(50% - 50px);
}
100% {
width: 140px;
height: 140px;
opacity: 0;
top: calc(50% - 70px);
left: calc(50% - 70px);
}
}
/* Colour the rings per item */
.ih-15__item:nth-child(1) .ih-15__ring {
border-color: #38bdf8;
}
.ih-15__item:nth-child(2) .ih-15__ring {
border-color: #c084fc;
}
.ih-15__item:nth-child(3) .ih-15__ring {
border-color: #4ade80;
}
.ih-15__name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-15__role {
font-size: 11px;
color: var(--muted);
}
.ih-15__socials {
display: flex;
gap: 8px;
margin-top: 4px;
}
.ih-15__social {
width: 26px;
height: 26px;
border-radius: 50%;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.08);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
transition: background 0.2s ease;
}
.ih-15__item:hover .ih-15__social {
background: rgba(255,255,255,0.1);
}
@media (prefers-reduced-motion: reduce) {
.ih-15__ring,
.ih-15__avatar {
animation: none!important;
transition: none;
}
}Here's a working CSS Image Hover Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Image Ripple Animation Hover
Source: https://codefronts.com/motion/css-image-hover-effects/css-image-ripple-animation-hover/
Concentric circle ripples emanate outward from a circular avatar on hover, driven by staggered keyframe animations on sibling span elements.
## HTML
```html
<div class="ih-15">
<div class="ih-15__grid">
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--1">👩🚀</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Dr. Elena Vasquez</p>
<p class="ih-15__role">Mission Architect</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--2">🧙</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Orion Blackwood</p>
<p class="ih-15__role">AI Research Lead</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--3">👩🌾</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Freya Lindqvist</p>
<p class="ih-15__role">Growth Engineer</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
</div>
</div>
```
## CSS
```css
.ih-15,
.ih-15 *,
.ih-15 *::before,
.ih-15 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-15 ::selection {
background: #2dd4bf;
color: #000;
}
.ih-15 {
--accent: #2dd4bf;
--bg: #060d0d;
--text: #f1f5f9;
--muted: #64748b;
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-15__item {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
cursor: pointer;
}
/* Ripple container — must be position:relative so pseudo rings use absolute */
.ih-15__frame {
position: relative;
width: 140px;
height: 140px;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__avatar {
width: 100px;
height: 100px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 42px;
position: relative;
z-index: 2;
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1);
}
.ih-15__avatar--1 {
background: radial-gradient(circle,#1e3a5f,#0369a1);
}
.ih-15__avatar--2 {
background: radial-gradient(circle,#3b0764,#7e22ce);
}
.ih-15__avatar--3 {
background: radial-gradient(circle,#052e16,#15803d);
}
.ih-15__item:hover .ih-15__avatar {
transform: scale(1.08);
}
/* Three ripple rings using sibling spans — keyframe scales + fades */
.ih-15__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--accent);
opacity: 0;
animation: none;
}
.ih-15__item:hover .ih-15__ring {
animation: ih-15-ripple 1.5s cubic-bezier(0,0.2,0.8,1) infinite;
}
.ih-15__ring:nth-child(2) {
animation-delay: 0s;
}
.ih-15__ring:nth-child(3) {
animation-delay: 0.5s;
}
.ih-15__ring:nth-child(4) {
animation-delay: 1s;
}
@keyframes ih-15-ripple {
0% {
width: 100px;
height: 100px;
opacity: 0.6;
top: calc(50% - 50px);
left: calc(50% - 50px);
}
100% {
width: 140px;
height: 140px;
opacity: 0;
top: calc(50% - 70px);
left: calc(50% - 70px);
}
}
/* Colour the rings per item */
.ih-15__item:nth-child(1) .ih-15__ring {
border-color: #38bdf8;
}
.ih-15__item:nth-child(2) .ih-15__ring {
border-color: #c084fc;
}
.ih-15__item:nth-child(3) .ih-15__ring {
border-color: #4ade80;
}
.ih-15__name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-15__role {
font-size: 11px;
color: var(--muted);
}
.ih-15__socials {
display: flex;
gap: 8px;
margin-top: 4px;
}
.ih-15__social {
width: 26px;
height: 26px;
border-radius: 50%;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.08);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
transition: background 0.2s ease;
}
.ih-15__item:hover .ih-15__social {
background: rgba(255,255,255,0.1);
}
@media (prefers-reduced-motion: reduce) {
.ih-15__ring,
.ih-15__avatar {
animation: none!important;
transition: none;
}
}
```Here's a working CSS Image Hover Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Image Ripple Animation Hover
Source: https://codefronts.com/motion/css-image-hover-effects/css-image-ripple-animation-hover/
Concentric circle ripples emanate outward from a circular avatar on hover, driven by staggered keyframe animations on sibling span elements.
## HTML
```html
<div class="ih-15">
<div class="ih-15__grid">
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--1">👩🚀</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Dr. Elena Vasquez</p>
<p class="ih-15__role">Mission Architect</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--2">🧙</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Orion Blackwood</p>
<p class="ih-15__role">AI Research Lead</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
<div class="ih-15__item">
<div class="ih-15__frame">
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<span class="ih-15__ring"></span>
<div class="ih-15__avatar ih-15__avatar--3">👩🌾</div>
</div>
<div style="text-align:center">
<p class="ih-15__name">Freya Lindqvist</p>
<p class="ih-15__role">Growth Engineer</p>
<div class="ih-15__socials">
<span class="ih-15__social">𝕏</span>
<span class="ih-15__social">in</span>
<span class="ih-15__social">gh</span>
</div>
</div>
</div>
</div>
</div>
```
## CSS
```css
.ih-15,
.ih-15 *,
.ih-15 *::before,
.ih-15 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-15 ::selection {
background: #2dd4bf;
color: #000;
}
.ih-15 {
--accent: #2dd4bf;
--bg: #060d0d;
--text: #f1f5f9;
--muted: #64748b;
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-15__item {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
cursor: pointer;
}
/* Ripple container — must be position:relative so pseudo rings use absolute */
.ih-15__frame {
position: relative;
width: 140px;
height: 140px;
display: flex;
align-items: center;
justify-content: center;
}
.ih-15__avatar {
width: 100px;
height: 100px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 42px;
position: relative;
z-index: 2;
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1);
}
.ih-15__avatar--1 {
background: radial-gradient(circle,#1e3a5f,#0369a1);
}
.ih-15__avatar--2 {
background: radial-gradient(circle,#3b0764,#7e22ce);
}
.ih-15__avatar--3 {
background: radial-gradient(circle,#052e16,#15803d);
}
.ih-15__item:hover .ih-15__avatar {
transform: scale(1.08);
}
/* Three ripple rings using sibling spans — keyframe scales + fades */
.ih-15__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--accent);
opacity: 0;
animation: none;
}
.ih-15__item:hover .ih-15__ring {
animation: ih-15-ripple 1.5s cubic-bezier(0,0.2,0.8,1) infinite;
}
.ih-15__ring:nth-child(2) {
animation-delay: 0s;
}
.ih-15__ring:nth-child(3) {
animation-delay: 0.5s;
}
.ih-15__ring:nth-child(4) {
animation-delay: 1s;
}
@keyframes ih-15-ripple {
0% {
width: 100px;
height: 100px;
opacity: 0.6;
top: calc(50% - 50px);
left: calc(50% - 50px);
}
100% {
width: 140px;
height: 140px;
opacity: 0;
top: calc(50% - 70px);
left: calc(50% - 70px);
}
}
/* Colour the rings per item */
.ih-15__item:nth-child(1) .ih-15__ring {
border-color: #38bdf8;
}
.ih-15__item:nth-child(2) .ih-15__ring {
border-color: #c084fc;
}
.ih-15__item:nth-child(3) .ih-15__ring {
border-color: #4ade80;
}
.ih-15__name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-15__role {
font-size: 11px;
color: var(--muted);
}
.ih-15__socials {
display: flex;
gap: 8px;
margin-top: 4px;
}
.ih-15__social {
width: 26px;
height: 26px;
border-radius: 50%;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.08);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
transition: background 0.2s ease;
}
.ih-15__item:hover .ih-15__social {
background: rgba(255,255,255,0.1);
}
@media (prefers-reduced-motion: reduce) {
.ih-15__ring,
.ih-15__avatar {
animation: none!important;
transition: none;
}
}
```How this works
Three span elements are positioned absolutely at the centre of the avatar frame with border-radius: 50% and a coloured border. At rest they have opacity: 0 and no animation. On parent hover, each receives an animation: ih-15-ripple 1.5s with staggered delays (0s, 0.5s, 1s) so they fire sequentially. The keyframe expands the element from the avatar's exact diameter (100px) to the frame boundary (140px) while fading opacity from 0.6 to 0. Because width/height are animated in the keyframe (not transform), the rings expand from the true centre.
The animation: none at rest combined with the hover-added animation means the ring is completely inactive when not hovered, consuming zero compositor resources.
Make it yours
- Switch from
width/heightkeyframe expansion totransform: scale()with a fixed-size element for better GPU performance on pages with many avatar rings. - Increase the ring count by adding more
spans and extending the delay series:0s, 0.33s, 0.66s, 1sfor four rings. - Change the ring style from a full border to a dashed or dotted border for a technical/radar aesthetic.
- Apply the animation permanently (remove the hover condition) for notification badges or "live" status indicators on profile images.
- Use
conic-gradientinstead of a solid border for a spinning gradient ring effect alongside the ripple.
Gotchas — read before shipping
- Animating
widthandheightin the keyframe forces layout recalculation — usetransform: scale()on a fixed-size element in performance-critical contexts. - The animation must be set to
noneat rest and added via a:hoverselector — if it is always running (just invisible via opacity), it will consume animation thread resources even off-screen. - In Safari, an animation that references a fixed start size via a keyframe percentage and pixel values can have timing inconsistencies if the parent is resized — set explicit widths on the ring spans.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 43+ | 9+ | 16+ | 43+ |
CSS animation with keyframes is universally supported; the border-radius circle expansion technique works in all modern browsers.