12 CSS Ripple Effects06 / 12
CSS Sonar Ping Ripple Animation
A military-grade sonar scope: conic-gradient sweep arm with a glowing edge, four concentric range-circle grids, four animated blips that appear as the sweep passes and each sprout their own CSS ripple ring. Data readout panels and a blinking status line. Share Tech Mono + Orbitron on phosphor-green #001408.
Published
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-06">
<div class="rpl-06__panel">
<div class="rpl-06__hdr">
<h1>SONAR PING RIPPLE</h1>
<p>CSS conic-gradient sweep · animated contact blips</p>
</div>
<div class="rpl-06__scope">
<!-- Grid rings -->
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<!-- Sweep -->
<div class="rpl-06__sweep"></div>
<!-- Blips & their ripple rings -->
<div class="rpl-06__blip rpl-06__blip--a"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--a"></div>
<div class="rpl-06__blip rpl-06__blip--b"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--b"></div>
<div class="rpl-06__blip rpl-06__blip--c"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--c"></div>
<div class="rpl-06__blip rpl-06__blip--d"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--d"></div>
<!-- Center -->
<div class="rpl-06__center"></div>
</div>
<div class="rpl-06__readout">
<div class="rpl-06__data">
<div class="key">Contacts</div>
<div class="val">04</div>
</div>
<div class="rpl-06__data">
<div class="key">Sweep / min</div>
<div class="val">20 RPM</div>
</div>
<div class="rpl-06__data">
<div class="key">Range</div>
<div class="val">48 nmi</div>
</div>
<div class="rpl-06__data">
<div class="key">Mode</div>
<div class="val">ACTIVE</div>
</div>
</div>
<div class="rpl-06__status">▌ SCANNING · PURE CSS · NO CANVAS ▌</div>
</div>
</div><div class="rpl-06">
<div class="rpl-06__panel">
<div class="rpl-06__hdr">
<h1>SONAR PING RIPPLE</h1>
<p>CSS conic-gradient sweep · animated contact blips</p>
</div>
<div class="rpl-06__scope">
<!-- Grid rings -->
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<!-- Sweep -->
<div class="rpl-06__sweep"></div>
<!-- Blips & their ripple rings -->
<div class="rpl-06__blip rpl-06__blip--a"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--a"></div>
<div class="rpl-06__blip rpl-06__blip--b"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--b"></div>
<div class="rpl-06__blip rpl-06__blip--c"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--c"></div>
<div class="rpl-06__blip rpl-06__blip--d"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--d"></div>
<!-- Center -->
<div class="rpl-06__center"></div>
</div>
<div class="rpl-06__readout">
<div class="rpl-06__data">
<div class="key">Contacts</div>
<div class="val">04</div>
</div>
<div class="rpl-06__data">
<div class="key">Sweep / min</div>
<div class="val">20 RPM</div>
</div>
<div class="rpl-06__data">
<div class="key">Range</div>
<div class="val">48 nmi</div>
</div>
<div class="rpl-06__data">
<div class="key">Mode</div>
<div class="val">ACTIVE</div>
</div>
</div>
<div class="rpl-06__status">▌ SCANNING · PURE CSS · NO CANVAS ▌</div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Orbitron:wght@400;500;700&display=swap');
.rpl-06,
.rpl-06 *,
.rpl-06 *::before,
.rpl-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.rpl-06 ::selection {
background: #22c55e;
color: #001408;
}
.rpl-06 {
font-family: 'Share Tech Mono', monospace;
background: #001408;
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
color: #22c55e;
position: relative;
overflow: hidden;
}
/* dark grid lines */
.rpl-06::before {
content: '';
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(34,197,94,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(34,197,94,0.06) 1px, transparent 1px);
background-size: 40px 40px;
}
.rpl-06__panel {
position: relative;
z-index: 2;
width: min(520px, 100%);
display: flex;
flex-direction: column;
align-items: center;
gap: 28px;
}
/* ─── Sonar scope ─── */
.rpl-06__scope {
position: relative;
width: min(420px, 100%);
aspect-ratio: 1;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, #002810, #000c04 70%);
border: 2px solid rgba(34,197,94,0.3);
box-shadow: 0 0 0 1px rgba(34,197,94,0.1), 0 0 40px rgba(34,197,94,0.15), inset 0 0 60px rgba(0,0,0,0.7);
overflow: hidden;
}
/* Crosshairs */
.rpl-06__scope::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(0deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%), linear-gradient(90deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%);
pointer-events: none;
z-index: 3;
}
/* Concentric range rings */
.rpl-06__grid-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.18);
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.rpl-06__grid-ring:nth-child(1) {
width: 25%;
height: 25%;
}
.rpl-06__grid-ring:nth-child(2) {
width: 50%;
height: 50%;
}
.rpl-06__grid-ring:nth-child(3) {
width: 75%;
height: 75%;
}
.rpl-06__grid-ring:nth-child(4) {
width: 100%;
height: 100%;
border-color: rgba(34,197,94,0.3);
}
/* Rotating sweep arm */
.rpl-06__sweep {
position: absolute;
inset: 0;
border-radius: 50%;
background: conic-gradient(from 0deg, rgba(34,197,94,0.45) 0deg, rgba(34,197,94,0.15) 25deg, transparent 90deg);
animation: rpl-06-sweep 3s linear infinite;
z-index: 2;
}
@keyframes rpl-06-sweep {
to {
transform: rotate(360deg);
}
}
/* Sweep edge glow */
.rpl-06__sweep::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 2px;
background: linear-gradient(90deg, transparent, rgba(34,197,94,0.9));
transform-origin: left center;
transform: translateY(-1px) rotate(0deg);
animation: rpl-06-sweep 3s linear infinite;
filter: blur(1px);
}
/* Contact blips */
.rpl-06__blip {
position: absolute;
border-radius: 50%;
background: radial-gradient(circle, #86efac, #22c55e);
box-shadow: 0 0 8px #22c55e, 0 0 16px rgba(34,197,94,0.5);
z-index: 4;
animation: rpl-06-blip 3s linear infinite;
}
.rpl-06__blip--a {
width: 8px;
height: 8px;
left: 65%;
top: 32%;
animation-delay: 0.6s;
}
.rpl-06__blip--b {
width: 6px;
height: 6px;
left: 28%;
top: 61%;
animation-delay: 1.8s;
}
.rpl-06__blip--c {
width: 10px;
height: 10px;
left: 72%;
top: 68%;
animation-delay: 2.3s;
}
.rpl-06__blip--d {
width: 5px;
height: 5px;
left: 42%;
top: 22%;
animation-delay: 0.1s;
}
@keyframes rpl-06-blip {
0%,
30% {
opacity: 0;
}
35% {
opacity: 1;
}
60% {
opacity: 0.6;
}
90%,
100% {
opacity: 0;
}
}
/* Blip ripple effect */
.rpl-06__blip-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.7);
z-index: 3;
animation: rpl-06-blip-ring 3s linear infinite;
}
.rpl-06__blip-ring--a {
left: 65%;
top: 32%;
width: 0;
height: 0;
animation-delay: 0.7s;
}
.rpl-06__blip-ring--b {
left: 28%;
top: 61%;
width: 0;
height: 0;
animation-delay: 1.9s;
}
.rpl-06__blip-ring--c {
left: 72%;
top: 68%;
width: 0;
height: 0;
animation-delay: 2.4s;
}
.rpl-06__blip-ring--d {
left: 42%;
top: 22%;
width: 0;
height: 0;
animation-delay: 0.2s;
}
@keyframes rpl-06-blip-ring {
0%,
30% {
width: 0;
height: 0;
opacity: 0;
transform: translate(-50%,-50%);
}
35% {
opacity: 1;
}
80% {
width: 30px;
height: 30px;
opacity: 0;
transform: translate(-50%,-50%);
}
100% {
opacity: 0;
}
}
/* Center dot */
.rpl-06__center {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background: #22c55e;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
box-shadow: 0 0 10px #22c55e;
z-index: 5;
}
/* Readout panel */
.rpl-06__readout {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.rpl-06__data {
background: rgba(34,197,94,0.05);
border: 1px solid rgba(34,197,94,0.2);
border-radius: 6px;
padding: 12px 14px;
}
.rpl-06__data .key {
font-size: 0.62rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: rgba(34,197,94,0.5);
margin-bottom: 4px;
}
.rpl-06__data .val {
font-family: 'Orbitron';
font-size: 1rem;
font-weight: 500;
color: #86efac;
}
/* Header */
.rpl-06__hdr {
text-align: center;
width: 100%;
}
.rpl-06__hdr h1 {
font-family: 'Orbitron';
font-size: clamp(1rem, 3vw, 1.5rem);
font-weight: 700;
letter-spacing: 0.12em;
color: #22c55e;
text-shadow: 0 0 20px rgba(34,197,94,0.5);
}
.rpl-06__hdr p {
font-size: 0.75rem;
color: rgba(34,197,94,0.45);
margin-top: 6px;
letter-spacing: 0.1em;
}
/* Scrolling status line */
.rpl-06__status {
font-size: 0.72rem;
color: rgba(34,197,94,0.5);
text-align: center;
letter-spacing: 0.1em;
animation: rpl-06-blink 1.4s steps(2) infinite;
}
@keyframes rpl-06-blink {
50% {
opacity: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.rpl-06__sweep,
.rpl-06__sweep::after {
animation: none !important;
}
.rpl-06__blip,
.rpl-06__blip-ring,
.rpl-06__status {
animation: none !important;
opacity: 0.5;
}
}@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Orbitron:wght@400;500;700&display=swap');
.rpl-06,
.rpl-06 *,
.rpl-06 *::before,
.rpl-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.rpl-06 ::selection {
background: #22c55e;
color: #001408;
}
.rpl-06 {
font-family: 'Share Tech Mono', monospace;
background: #001408;
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
color: #22c55e;
position: relative;
overflow: hidden;
}
/* dark grid lines */
.rpl-06::before {
content: '';
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(34,197,94,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(34,197,94,0.06) 1px, transparent 1px);
background-size: 40px 40px;
}
.rpl-06__panel {
position: relative;
z-index: 2;
width: min(520px, 100%);
display: flex;
flex-direction: column;
align-items: center;
gap: 28px;
}
/* ─── Sonar scope ─── */
.rpl-06__scope {
position: relative;
width: min(420px, 100%);
aspect-ratio: 1;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, #002810, #000c04 70%);
border: 2px solid rgba(34,197,94,0.3);
box-shadow: 0 0 0 1px rgba(34,197,94,0.1), 0 0 40px rgba(34,197,94,0.15), inset 0 0 60px rgba(0,0,0,0.7);
overflow: hidden;
}
/* Crosshairs */
.rpl-06__scope::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(0deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%), linear-gradient(90deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%);
pointer-events: none;
z-index: 3;
}
/* Concentric range rings */
.rpl-06__grid-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.18);
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.rpl-06__grid-ring:nth-child(1) {
width: 25%;
height: 25%;
}
.rpl-06__grid-ring:nth-child(2) {
width: 50%;
height: 50%;
}
.rpl-06__grid-ring:nth-child(3) {
width: 75%;
height: 75%;
}
.rpl-06__grid-ring:nth-child(4) {
width: 100%;
height: 100%;
border-color: rgba(34,197,94,0.3);
}
/* Rotating sweep arm */
.rpl-06__sweep {
position: absolute;
inset: 0;
border-radius: 50%;
background: conic-gradient(from 0deg, rgba(34,197,94,0.45) 0deg, rgba(34,197,94,0.15) 25deg, transparent 90deg);
animation: rpl-06-sweep 3s linear infinite;
z-index: 2;
}
@keyframes rpl-06-sweep {
to {
transform: rotate(360deg);
}
}
/* Sweep edge glow */
.rpl-06__sweep::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 2px;
background: linear-gradient(90deg, transparent, rgba(34,197,94,0.9));
transform-origin: left center;
transform: translateY(-1px) rotate(0deg);
animation: rpl-06-sweep 3s linear infinite;
filter: blur(1px);
}
/* Contact blips */
.rpl-06__blip {
position: absolute;
border-radius: 50%;
background: radial-gradient(circle, #86efac, #22c55e);
box-shadow: 0 0 8px #22c55e, 0 0 16px rgba(34,197,94,0.5);
z-index: 4;
animation: rpl-06-blip 3s linear infinite;
}
.rpl-06__blip--a {
width: 8px;
height: 8px;
left: 65%;
top: 32%;
animation-delay: 0.6s;
}
.rpl-06__blip--b {
width: 6px;
height: 6px;
left: 28%;
top: 61%;
animation-delay: 1.8s;
}
.rpl-06__blip--c {
width: 10px;
height: 10px;
left: 72%;
top: 68%;
animation-delay: 2.3s;
}
.rpl-06__blip--d {
width: 5px;
height: 5px;
left: 42%;
top: 22%;
animation-delay: 0.1s;
}
@keyframes rpl-06-blip {
0%,
30% {
opacity: 0;
}
35% {
opacity: 1;
}
60% {
opacity: 0.6;
}
90%,
100% {
opacity: 0;
}
}
/* Blip ripple effect */
.rpl-06__blip-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.7);
z-index: 3;
animation: rpl-06-blip-ring 3s linear infinite;
}
.rpl-06__blip-ring--a {
left: 65%;
top: 32%;
width: 0;
height: 0;
animation-delay: 0.7s;
}
.rpl-06__blip-ring--b {
left: 28%;
top: 61%;
width: 0;
height: 0;
animation-delay: 1.9s;
}
.rpl-06__blip-ring--c {
left: 72%;
top: 68%;
width: 0;
height: 0;
animation-delay: 2.4s;
}
.rpl-06__blip-ring--d {
left: 42%;
top: 22%;
width: 0;
height: 0;
animation-delay: 0.2s;
}
@keyframes rpl-06-blip-ring {
0%,
30% {
width: 0;
height: 0;
opacity: 0;
transform: translate(-50%,-50%);
}
35% {
opacity: 1;
}
80% {
width: 30px;
height: 30px;
opacity: 0;
transform: translate(-50%,-50%);
}
100% {
opacity: 0;
}
}
/* Center dot */
.rpl-06__center {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background: #22c55e;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
box-shadow: 0 0 10px #22c55e;
z-index: 5;
}
/* Readout panel */
.rpl-06__readout {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.rpl-06__data {
background: rgba(34,197,94,0.05);
border: 1px solid rgba(34,197,94,0.2);
border-radius: 6px;
padding: 12px 14px;
}
.rpl-06__data .key {
font-size: 0.62rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: rgba(34,197,94,0.5);
margin-bottom: 4px;
}
.rpl-06__data .val {
font-family: 'Orbitron';
font-size: 1rem;
font-weight: 500;
color: #86efac;
}
/* Header */
.rpl-06__hdr {
text-align: center;
width: 100%;
}
.rpl-06__hdr h1 {
font-family: 'Orbitron';
font-size: clamp(1rem, 3vw, 1.5rem);
font-weight: 700;
letter-spacing: 0.12em;
color: #22c55e;
text-shadow: 0 0 20px rgba(34,197,94,0.5);
}
.rpl-06__hdr p {
font-size: 0.75rem;
color: rgba(34,197,94,0.45);
margin-top: 6px;
letter-spacing: 0.1em;
}
/* Scrolling status line */
.rpl-06__status {
font-size: 0.72rem;
color: rgba(34,197,94,0.5);
text-align: center;
letter-spacing: 0.1em;
animation: rpl-06-blink 1.4s steps(2) infinite;
}
@keyframes rpl-06-blink {
50% {
opacity: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.rpl-06__sweep,
.rpl-06__sweep::after {
animation: none !important;
}
.rpl-06__blip,
.rpl-06__blip-ring,
.rpl-06__status {
animation: none !important;
opacity: 0.5;
}
}Here's a working CSS Ripple 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 Sonar Ping Ripple Animation
Source: https://codefronts.com/motion/css-ripple-designs/css-sonar-ping-ripple-animation/
A military-grade sonar scope: conic-gradient sweep arm with a glowing edge, four concentric range-circle grids, four animated blips that appear as the sweep passes and each sprout their own CSS ripple ring. Data readout panels and a blinking status line. Share Tech Mono + Orbitron on phosphor-green #001408.
## HTML
```html
<div class="rpl-06">
<div class="rpl-06__panel">
<div class="rpl-06__hdr">
<h1>SONAR PING RIPPLE</h1>
<p>CSS conic-gradient sweep · animated contact blips</p>
</div>
<div class="rpl-06__scope">
<!-- Grid rings -->
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<!-- Sweep -->
<div class="rpl-06__sweep"></div>
<!-- Blips & their ripple rings -->
<div class="rpl-06__blip rpl-06__blip--a"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--a"></div>
<div class="rpl-06__blip rpl-06__blip--b"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--b"></div>
<div class="rpl-06__blip rpl-06__blip--c"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--c"></div>
<div class="rpl-06__blip rpl-06__blip--d"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--d"></div>
<!-- Center -->
<div class="rpl-06__center"></div>
</div>
<div class="rpl-06__readout">
<div class="rpl-06__data">
<div class="key">Contacts</div>
<div class="val">04</div>
</div>
<div class="rpl-06__data">
<div class="key">Sweep / min</div>
<div class="val">20 RPM</div>
</div>
<div class="rpl-06__data">
<div class="key">Range</div>
<div class="val">48 nmi</div>
</div>
<div class="rpl-06__data">
<div class="key">Mode</div>
<div class="val">ACTIVE</div>
</div>
</div>
<div class="rpl-06__status">▌ SCANNING · PURE CSS · NO CANVAS ▌</div>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Orbitron:wght@400;500;700&display=swap');
.rpl-06,
.rpl-06 *,
.rpl-06 *::before,
.rpl-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.rpl-06 ::selection {
background: #22c55e;
color: #001408;
}
.rpl-06 {
font-family: 'Share Tech Mono', monospace;
background: #001408;
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
color: #22c55e;
position: relative;
overflow: hidden;
}
/* dark grid lines */
.rpl-06::before {
content: '';
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(34,197,94,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(34,197,94,0.06) 1px, transparent 1px);
background-size: 40px 40px;
}
.rpl-06__panel {
position: relative;
z-index: 2;
width: min(520px, 100%);
display: flex;
flex-direction: column;
align-items: center;
gap: 28px;
}
/* ─── Sonar scope ─── */
.rpl-06__scope {
position: relative;
width: min(420px, 100%);
aspect-ratio: 1;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, #002810, #000c04 70%);
border: 2px solid rgba(34,197,94,0.3);
box-shadow: 0 0 0 1px rgba(34,197,94,0.1), 0 0 40px rgba(34,197,94,0.15), inset 0 0 60px rgba(0,0,0,0.7);
overflow: hidden;
}
/* Crosshairs */
.rpl-06__scope::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(0deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%), linear-gradient(90deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%);
pointer-events: none;
z-index: 3;
}
/* Concentric range rings */
.rpl-06__grid-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.18);
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.rpl-06__grid-ring:nth-child(1) {
width: 25%;
height: 25%;
}
.rpl-06__grid-ring:nth-child(2) {
width: 50%;
height: 50%;
}
.rpl-06__grid-ring:nth-child(3) {
width: 75%;
height: 75%;
}
.rpl-06__grid-ring:nth-child(4) {
width: 100%;
height: 100%;
border-color: rgba(34,197,94,0.3);
}
/* Rotating sweep arm */
.rpl-06__sweep {
position: absolute;
inset: 0;
border-radius: 50%;
background: conic-gradient(from 0deg, rgba(34,197,94,0.45) 0deg, rgba(34,197,94,0.15) 25deg, transparent 90deg);
animation: rpl-06-sweep 3s linear infinite;
z-index: 2;
}
@keyframes rpl-06-sweep {
to {
transform: rotate(360deg);
}
}
/* Sweep edge glow */
.rpl-06__sweep::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 2px;
background: linear-gradient(90deg, transparent, rgba(34,197,94,0.9));
transform-origin: left center;
transform: translateY(-1px) rotate(0deg);
animation: rpl-06-sweep 3s linear infinite;
filter: blur(1px);
}
/* Contact blips */
.rpl-06__blip {
position: absolute;
border-radius: 50%;
background: radial-gradient(circle, #86efac, #22c55e);
box-shadow: 0 0 8px #22c55e, 0 0 16px rgba(34,197,94,0.5);
z-index: 4;
animation: rpl-06-blip 3s linear infinite;
}
.rpl-06__blip--a {
width: 8px;
height: 8px;
left: 65%;
top: 32%;
animation-delay: 0.6s;
}
.rpl-06__blip--b {
width: 6px;
height: 6px;
left: 28%;
top: 61%;
animation-delay: 1.8s;
}
.rpl-06__blip--c {
width: 10px;
height: 10px;
left: 72%;
top: 68%;
animation-delay: 2.3s;
}
.rpl-06__blip--d {
width: 5px;
height: 5px;
left: 42%;
top: 22%;
animation-delay: 0.1s;
}
@keyframes rpl-06-blip {
0%,
30% {
opacity: 0;
}
35% {
opacity: 1;
}
60% {
opacity: 0.6;
}
90%,
100% {
opacity: 0;
}
}
/* Blip ripple effect */
.rpl-06__blip-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.7);
z-index: 3;
animation: rpl-06-blip-ring 3s linear infinite;
}
.rpl-06__blip-ring--a {
left: 65%;
top: 32%;
width: 0;
height: 0;
animation-delay: 0.7s;
}
.rpl-06__blip-ring--b {
left: 28%;
top: 61%;
width: 0;
height: 0;
animation-delay: 1.9s;
}
.rpl-06__blip-ring--c {
left: 72%;
top: 68%;
width: 0;
height: 0;
animation-delay: 2.4s;
}
.rpl-06__blip-ring--d {
left: 42%;
top: 22%;
width: 0;
height: 0;
animation-delay: 0.2s;
}
@keyframes rpl-06-blip-ring {
0%,
30% {
width: 0;
height: 0;
opacity: 0;
transform: translate(-50%,-50%);
}
35% {
opacity: 1;
}
80% {
width: 30px;
height: 30px;
opacity: 0;
transform: translate(-50%,-50%);
}
100% {
opacity: 0;
}
}
/* Center dot */
.rpl-06__center {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background: #22c55e;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
box-shadow: 0 0 10px #22c55e;
z-index: 5;
}
/* Readout panel */
.rpl-06__readout {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.rpl-06__data {
background: rgba(34,197,94,0.05);
border: 1px solid rgba(34,197,94,0.2);
border-radius: 6px;
padding: 12px 14px;
}
.rpl-06__data .key {
font-size: 0.62rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: rgba(34,197,94,0.5);
margin-bottom: 4px;
}
.rpl-06__data .val {
font-family: 'Orbitron';
font-size: 1rem;
font-weight: 500;
color: #86efac;
}
/* Header */
.rpl-06__hdr {
text-align: center;
width: 100%;
}
.rpl-06__hdr h1 {
font-family: 'Orbitron';
font-size: clamp(1rem, 3vw, 1.5rem);
font-weight: 700;
letter-spacing: 0.12em;
color: #22c55e;
text-shadow: 0 0 20px rgba(34,197,94,0.5);
}
.rpl-06__hdr p {
font-size: 0.75rem;
color: rgba(34,197,94,0.45);
margin-top: 6px;
letter-spacing: 0.1em;
}
/* Scrolling status line */
.rpl-06__status {
font-size: 0.72rem;
color: rgba(34,197,94,0.5);
text-align: center;
letter-spacing: 0.1em;
animation: rpl-06-blink 1.4s steps(2) infinite;
}
@keyframes rpl-06-blink {
50% {
opacity: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.rpl-06__sweep,
.rpl-06__sweep::after {
animation: none !important;
}
.rpl-06__blip,
.rpl-06__blip-ring,
.rpl-06__status {
animation: none !important;
opacity: 0.5;
}
}
```Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Ripple 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 Sonar Ping Ripple Animation
Source: https://codefronts.com/motion/css-ripple-designs/css-sonar-ping-ripple-animation/
A military-grade sonar scope: conic-gradient sweep arm with a glowing edge, four concentric range-circle grids, four animated blips that appear as the sweep passes and each sprout their own CSS ripple ring. Data readout panels and a blinking status line. Share Tech Mono + Orbitron on phosphor-green #001408.
## HTML
```html
<div class="rpl-06">
<div class="rpl-06__panel">
<div class="rpl-06__hdr">
<h1>SONAR PING RIPPLE</h1>
<p>CSS conic-gradient sweep · animated contact blips</p>
</div>
<div class="rpl-06__scope">
<!-- Grid rings -->
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<div class="rpl-06__grid-ring"></div>
<!-- Sweep -->
<div class="rpl-06__sweep"></div>
<!-- Blips & their ripple rings -->
<div class="rpl-06__blip rpl-06__blip--a"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--a"></div>
<div class="rpl-06__blip rpl-06__blip--b"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--b"></div>
<div class="rpl-06__blip rpl-06__blip--c"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--c"></div>
<div class="rpl-06__blip rpl-06__blip--d"></div>
<div class="rpl-06__blip-ring rpl-06__blip-ring--d"></div>
<!-- Center -->
<div class="rpl-06__center"></div>
</div>
<div class="rpl-06__readout">
<div class="rpl-06__data">
<div class="key">Contacts</div>
<div class="val">04</div>
</div>
<div class="rpl-06__data">
<div class="key">Sweep / min</div>
<div class="val">20 RPM</div>
</div>
<div class="rpl-06__data">
<div class="key">Range</div>
<div class="val">48 nmi</div>
</div>
<div class="rpl-06__data">
<div class="key">Mode</div>
<div class="val">ACTIVE</div>
</div>
</div>
<div class="rpl-06__status">▌ SCANNING · PURE CSS · NO CANVAS ▌</div>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Orbitron:wght@400;500;700&display=swap');
.rpl-06,
.rpl-06 *,
.rpl-06 *::before,
.rpl-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.rpl-06 ::selection {
background: #22c55e;
color: #001408;
}
.rpl-06 {
font-family: 'Share Tech Mono', monospace;
background: #001408;
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
color: #22c55e;
position: relative;
overflow: hidden;
}
/* dark grid lines */
.rpl-06::before {
content: '';
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(34,197,94,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(34,197,94,0.06) 1px, transparent 1px);
background-size: 40px 40px;
}
.rpl-06__panel {
position: relative;
z-index: 2;
width: min(520px, 100%);
display: flex;
flex-direction: column;
align-items: center;
gap: 28px;
}
/* ─── Sonar scope ─── */
.rpl-06__scope {
position: relative;
width: min(420px, 100%);
aspect-ratio: 1;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, #002810, #000c04 70%);
border: 2px solid rgba(34,197,94,0.3);
box-shadow: 0 0 0 1px rgba(34,197,94,0.1), 0 0 40px rgba(34,197,94,0.15), inset 0 0 60px rgba(0,0,0,0.7);
overflow: hidden;
}
/* Crosshairs */
.rpl-06__scope::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(0deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%), linear-gradient(90deg, transparent 49.5%, rgba(34,197,94,0.15) 49.5%, rgba(34,197,94,0.15) 50.5%, transparent 50.5%);
pointer-events: none;
z-index: 3;
}
/* Concentric range rings */
.rpl-06__grid-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.18);
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.rpl-06__grid-ring:nth-child(1) {
width: 25%;
height: 25%;
}
.rpl-06__grid-ring:nth-child(2) {
width: 50%;
height: 50%;
}
.rpl-06__grid-ring:nth-child(3) {
width: 75%;
height: 75%;
}
.rpl-06__grid-ring:nth-child(4) {
width: 100%;
height: 100%;
border-color: rgba(34,197,94,0.3);
}
/* Rotating sweep arm */
.rpl-06__sweep {
position: absolute;
inset: 0;
border-radius: 50%;
background: conic-gradient(from 0deg, rgba(34,197,94,0.45) 0deg, rgba(34,197,94,0.15) 25deg, transparent 90deg);
animation: rpl-06-sweep 3s linear infinite;
z-index: 2;
}
@keyframes rpl-06-sweep {
to {
transform: rotate(360deg);
}
}
/* Sweep edge glow */
.rpl-06__sweep::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 2px;
background: linear-gradient(90deg, transparent, rgba(34,197,94,0.9));
transform-origin: left center;
transform: translateY(-1px) rotate(0deg);
animation: rpl-06-sweep 3s linear infinite;
filter: blur(1px);
}
/* Contact blips */
.rpl-06__blip {
position: absolute;
border-radius: 50%;
background: radial-gradient(circle, #86efac, #22c55e);
box-shadow: 0 0 8px #22c55e, 0 0 16px rgba(34,197,94,0.5);
z-index: 4;
animation: rpl-06-blip 3s linear infinite;
}
.rpl-06__blip--a {
width: 8px;
height: 8px;
left: 65%;
top: 32%;
animation-delay: 0.6s;
}
.rpl-06__blip--b {
width: 6px;
height: 6px;
left: 28%;
top: 61%;
animation-delay: 1.8s;
}
.rpl-06__blip--c {
width: 10px;
height: 10px;
left: 72%;
top: 68%;
animation-delay: 2.3s;
}
.rpl-06__blip--d {
width: 5px;
height: 5px;
left: 42%;
top: 22%;
animation-delay: 0.1s;
}
@keyframes rpl-06-blip {
0%,
30% {
opacity: 0;
}
35% {
opacity: 1;
}
60% {
opacity: 0.6;
}
90%,
100% {
opacity: 0;
}
}
/* Blip ripple effect */
.rpl-06__blip-ring {
position: absolute;
border-radius: 50%;
border: 1px solid rgba(34,197,94,0.7);
z-index: 3;
animation: rpl-06-blip-ring 3s linear infinite;
}
.rpl-06__blip-ring--a {
left: 65%;
top: 32%;
width: 0;
height: 0;
animation-delay: 0.7s;
}
.rpl-06__blip-ring--b {
left: 28%;
top: 61%;
width: 0;
height: 0;
animation-delay: 1.9s;
}
.rpl-06__blip-ring--c {
left: 72%;
top: 68%;
width: 0;
height: 0;
animation-delay: 2.4s;
}
.rpl-06__blip-ring--d {
left: 42%;
top: 22%;
width: 0;
height: 0;
animation-delay: 0.2s;
}
@keyframes rpl-06-blip-ring {
0%,
30% {
width: 0;
height: 0;
opacity: 0;
transform: translate(-50%,-50%);
}
35% {
opacity: 1;
}
80% {
width: 30px;
height: 30px;
opacity: 0;
transform: translate(-50%,-50%);
}
100% {
opacity: 0;
}
}
/* Center dot */
.rpl-06__center {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background: #22c55e;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
box-shadow: 0 0 10px #22c55e;
z-index: 5;
}
/* Readout panel */
.rpl-06__readout {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.rpl-06__data {
background: rgba(34,197,94,0.05);
border: 1px solid rgba(34,197,94,0.2);
border-radius: 6px;
padding: 12px 14px;
}
.rpl-06__data .key {
font-size: 0.62rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: rgba(34,197,94,0.5);
margin-bottom: 4px;
}
.rpl-06__data .val {
font-family: 'Orbitron';
font-size: 1rem;
font-weight: 500;
color: #86efac;
}
/* Header */
.rpl-06__hdr {
text-align: center;
width: 100%;
}
.rpl-06__hdr h1 {
font-family: 'Orbitron';
font-size: clamp(1rem, 3vw, 1.5rem);
font-weight: 700;
letter-spacing: 0.12em;
color: #22c55e;
text-shadow: 0 0 20px rgba(34,197,94,0.5);
}
.rpl-06__hdr p {
font-size: 0.75rem;
color: rgba(34,197,94,0.45);
margin-top: 6px;
letter-spacing: 0.1em;
}
/* Scrolling status line */
.rpl-06__status {
font-size: 0.72rem;
color: rgba(34,197,94,0.5);
text-align: center;
letter-spacing: 0.1em;
animation: rpl-06-blink 1.4s steps(2) infinite;
}
@keyframes rpl-06-blink {
50% {
opacity: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.rpl-06__sweep,
.rpl-06__sweep::after {
animation: none !important;
}
.rpl-06__blip,
.rpl-06__blip-ring,
.rpl-06__status {
animation: none !important;
opacity: 0.5;
}
}
```