29 / 33
All 33 in 33 CSS Card Hover Effects
- 013D Tilt & Parallax Card Effects
- 02Glowing Gradient & Glassmorphic Borders
- 03Image Zoom with Content Reveal / Slide-Up
- 043D Flip Cards (Front to Back)
- 05Parent Blur / Sibling De-emphasis (Focus States)
- 06Minimalist Elevation & Dynamic Shadows
- 07Elastic Lift
- 08Gradient Border Draw
- 09Stacked Reveal
- 10Holographic Shimmer
- 11Curtain Reveal
- 12Corner Peel
- 13Neon Sign
- 14Scanline
- 15Depth Parallax
- 16Spotlight
- 173D Tilt
- 18Slide Up Content
- 19Flip Card
- 20Glitch Card
- 21Gradient Rotate
- 22Border Morph
- 23Magnetic Float
- 24Typewriter Reveal
- 25Overlay Slide
- 26Grain Texture
- 27Frosted Glass Intensify
- 28Blueprint Reveal
- 29Shockwave
- 30Color Burn
- 31Prismatic Sweep
- 32Book Open
- 33Aurora
Shockwave
An energy/tech card that fires concentric ripple rings outward from the exact point where the cursor enters, with staggered colored waves. Best for power, audio, gaming, and CTA cards that should feel reactive and kinetic.
Build interactive UI like this from scratch: 20 HTML, CSS & JavaScript projects
ZTM · JavaScript Web Projects · 30‑day money-back guarantee · Affiliate link
The code
<div class="card-29">
<article class="card-29__card" data-card-29="root">
<div class="card-29__inner">
<span class="card-29__tag">// Energy Core</span>
<h2 class="card-29__title">Pulse<br>Reactor</h2>
<p class="card-29__desc">Every interaction sends a wave outward. Hover anywhere — the ripple starts where you enter.</p>
<span class="card-29__btn">Discharge ⚡</span>
</div>
</article>
</div><div class="card-29">
<article class="card-29__card" data-card-29="root">
<div class="card-29__inner">
<span class="card-29__tag">// Energy Core</span>
<h2 class="card-29__title">Pulse<br>Reactor</h2>
<p class="card-29__desc">Every interaction sends a wave outward. Hover anywhere — the ripple starts where you enter.</p>
<span class="card-29__btn">Discharge ⚡</span>
</div>
</article>
</div>@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@500;700&family=Inter:wght@400;500&display=swap');
.card-29,
.card-29 *,
.card-29 *::before,
.card-29 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-29 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #07101a;
font-family: 'Inter', sans-serif;
padding: 2rem;
}
.card-29__card {
--card-29-x: 50%;
--card-29-y: 50%;
position: relative;
width: 340px;
height: 440px;
border-radius: 18px;
cursor: pointer;
overflow: hidden;
background: radial-gradient(circle at 50% 40%, #0e2236, #060d16);
border: 1px solid rgba(60,180,255,0.18);
}
.card-29__card::before {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 2px solid rgba(80,200,255,0.7);
box-shadow: 0 0 30px rgba(80,200,255,0.5);
z-index: 1;
}
.card-29__card:hover::before {
animation: card-29-ring 0.9s cubic-bezier(0.2,0.6,0.3,1) forwards;
}
@keyframes card-29-ring {
0% {
transform: translate(-50%,-50%) scale(0);
opacity: 0.9;
}
100% {
transform: translate(-50%,-50%) scale(60);
opacity: 0;
}
}
.card-29__card::after {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 1px solid rgba(160,90,255,0.6);
z-index: 1;
}
.card-29__card:hover::after {
animation: card-29-ring 1.1s cubic-bezier(0.2,0.6,0.3,1) 0.12s forwards;
}
.card-29__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #dceaf7;
}
.card-29__tag {
font-family: 'Chakra Petch', sans-serif;
font-size: 0.72rem;
letter-spacing: 0.24em;
text-transform: uppercase;
color: #4fc3ff;
}
.card-29__title {
font-family: 'Chakra Petch', sans-serif;
font-weight: 700;
font-size: 2.6rem;
line-height: 0.95;
}
.card-29__desc {
font-size: 0.86rem;
line-height: 1.6;
color: #8fa6bb;
}
.card-29__btn {
align-self: flex-start;
font-family: 'Chakra Petch', sans-serif;
font-size: 0.85rem;
letter-spacing: 0.06em;
padding: 0.7rem 1.5rem;
border-radius: 8px;
border: 1px solid rgba(80,200,255,0.4);
color: #4fc3ff;
background: rgba(80,200,255,0.08);
transition: background 0.3s ease;
}
.card-29__card:hover .card-29__btn {
background: rgba(80,200,255,0.18);
}
@media (prefers-reduced-motion: reduce) {
.card-29__card::before,
.card-29__card::after {
animation: none !important;
}
}@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@500;700&family=Inter:wght@400;500&display=swap');
.card-29,
.card-29 *,
.card-29 *::before,
.card-29 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-29 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #07101a;
font-family: 'Inter', sans-serif;
padding: 2rem;
}
.card-29__card {
--card-29-x: 50%;
--card-29-y: 50%;
position: relative;
width: 340px;
height: 440px;
border-radius: 18px;
cursor: pointer;
overflow: hidden;
background: radial-gradient(circle at 50% 40%, #0e2236, #060d16);
border: 1px solid rgba(60,180,255,0.18);
}
.card-29__card::before {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 2px solid rgba(80,200,255,0.7);
box-shadow: 0 0 30px rgba(80,200,255,0.5);
z-index: 1;
}
.card-29__card:hover::before {
animation: card-29-ring 0.9s cubic-bezier(0.2,0.6,0.3,1) forwards;
}
@keyframes card-29-ring {
0% {
transform: translate(-50%,-50%) scale(0);
opacity: 0.9;
}
100% {
transform: translate(-50%,-50%) scale(60);
opacity: 0;
}
}
.card-29__card::after {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 1px solid rgba(160,90,255,0.6);
z-index: 1;
}
.card-29__card:hover::after {
animation: card-29-ring 1.1s cubic-bezier(0.2,0.6,0.3,1) 0.12s forwards;
}
.card-29__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #dceaf7;
}
.card-29__tag {
font-family: 'Chakra Petch', sans-serif;
font-size: 0.72rem;
letter-spacing: 0.24em;
text-transform: uppercase;
color: #4fc3ff;
}
.card-29__title {
font-family: 'Chakra Petch', sans-serif;
font-weight: 700;
font-size: 2.6rem;
line-height: 0.95;
}
.card-29__desc {
font-size: 0.86rem;
line-height: 1.6;
color: #8fa6bb;
}
.card-29__btn {
align-self: flex-start;
font-family: 'Chakra Petch', sans-serif;
font-size: 0.85rem;
letter-spacing: 0.06em;
padding: 0.7rem 1.5rem;
border-radius: 8px;
border: 1px solid rgba(80,200,255,0.4);
color: #4fc3ff;
background: rgba(80,200,255,0.08);
transition: background 0.3s ease;
}
.card-29__card:hover .card-29__btn {
background: rgba(80,200,255,0.18);
}
@media (prefers-reduced-motion: reduce) {
.card-29__card::before,
.card-29__card::after {
animation: none !important;
}
}(() => {
const root = document.querySelector('.card-29');
if (!root) return;
const c = root.querySelector('[data-card-29="root"]');
if (!c) return;
c.addEventListener('mouseenter', (e) => {
const r = c.getBoundingClientRect();
c.style.setProperty('--card-29-x', `${e.clientX - r.left}px`);
c.style.setProperty('--card-29-y', `${e.clientY - r.top}px`);
});
})();(() => {
const root = document.querySelector('.card-29');
if (!root) return;
const c = root.querySelector('[data-card-29="root"]');
if (!c) return;
c.addEventListener('mouseenter', (e) => {
const r = c.getBoundingClientRect();
c.style.setProperty('--card-29-x', `${e.clientX - r.left}px`);
c.style.setProperty('--card-29-y', `${e.clientY - r.top}px`);
});
})();Here's a working CSS Card 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: Shockwave
Source: https://codefronts.com/motion/css-card-hover-effects/shockwave/
An energy/tech card that fires concentric ripple rings outward from the exact point where the cursor enters, with staggered colored waves. Best for power, audio, gaming, and CTA cards that should feel reactive and kinetic.
## HTML
```html
<div class="card-29">
<article class="card-29__card" data-card-29="root">
<div class="card-29__inner">
<span class="card-29__tag">// Energy Core</span>
<h2 class="card-29__title">Pulse<br>Reactor</h2>
<p class="card-29__desc">Every interaction sends a wave outward. Hover anywhere — the ripple starts where you enter.</p>
<span class="card-29__btn">Discharge ⚡</span>
</div>
</article>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@500;700&family=Inter:wght@400;500&display=swap');
.card-29,
.card-29 *,
.card-29 *::before,
.card-29 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-29 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #07101a;
font-family: 'Inter', sans-serif;
padding: 2rem;
}
.card-29__card {
--card-29-x: 50%;
--card-29-y: 50%;
position: relative;
width: 340px;
height: 440px;
border-radius: 18px;
cursor: pointer;
overflow: hidden;
background: radial-gradient(circle at 50% 40%, #0e2236, #060d16);
border: 1px solid rgba(60,180,255,0.18);
}
.card-29__card::before {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 2px solid rgba(80,200,255,0.7);
box-shadow: 0 0 30px rgba(80,200,255,0.5);
z-index: 1;
}
.card-29__card:hover::before {
animation: card-29-ring 0.9s cubic-bezier(0.2,0.6,0.3,1) forwards;
}
@keyframes card-29-ring {
0% {
transform: translate(-50%,-50%) scale(0);
opacity: 0.9;
}
100% {
transform: translate(-50%,-50%) scale(60);
opacity: 0;
}
}
.card-29__card::after {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 1px solid rgba(160,90,255,0.6);
z-index: 1;
}
.card-29__card:hover::after {
animation: card-29-ring 1.1s cubic-bezier(0.2,0.6,0.3,1) 0.12s forwards;
}
.card-29__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #dceaf7;
}
.card-29__tag {
font-family: 'Chakra Petch', sans-serif;
font-size: 0.72rem;
letter-spacing: 0.24em;
text-transform: uppercase;
color: #4fc3ff;
}
.card-29__title {
font-family: 'Chakra Petch', sans-serif;
font-weight: 700;
font-size: 2.6rem;
line-height: 0.95;
}
.card-29__desc {
font-size: 0.86rem;
line-height: 1.6;
color: #8fa6bb;
}
.card-29__btn {
align-self: flex-start;
font-family: 'Chakra Petch', sans-serif;
font-size: 0.85rem;
letter-spacing: 0.06em;
padding: 0.7rem 1.5rem;
border-radius: 8px;
border: 1px solid rgba(80,200,255,0.4);
color: #4fc3ff;
background: rgba(80,200,255,0.08);
transition: background 0.3s ease;
}
.card-29__card:hover .card-29__btn {
background: rgba(80,200,255,0.18);
}
@media (prefers-reduced-motion: reduce) {
.card-29__card::before,
.card-29__card::after {
animation: none !important;
}
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.card-29');
if (!root) return;
const c = root.querySelector('[data-card-29="root"]');
if (!c) return;
c.addEventListener('mouseenter', (e) => {
const r = c.getBoundingClientRect();
c.style.setProperty('--card-29-x', `${e.clientX - r.left}px`);
c.style.setProperty('--card-29-y', `${e.clientY - r.top}px`);
});
})();
```Here's a working CSS Card 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: Shockwave
Source: https://codefronts.com/motion/css-card-hover-effects/shockwave/
An energy/tech card that fires concentric ripple rings outward from the exact point where the cursor enters, with staggered colored waves. Best for power, audio, gaming, and CTA cards that should feel reactive and kinetic.
## HTML
```html
<div class="card-29">
<article class="card-29__card" data-card-29="root">
<div class="card-29__inner">
<span class="card-29__tag">// Energy Core</span>
<h2 class="card-29__title">Pulse<br>Reactor</h2>
<p class="card-29__desc">Every interaction sends a wave outward. Hover anywhere — the ripple starts where you enter.</p>
<span class="card-29__btn">Discharge ⚡</span>
</div>
</article>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@500;700&family=Inter:wght@400;500&display=swap');
.card-29,
.card-29 *,
.card-29 *::before,
.card-29 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-29 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #07101a;
font-family: 'Inter', sans-serif;
padding: 2rem;
}
.card-29__card {
--card-29-x: 50%;
--card-29-y: 50%;
position: relative;
width: 340px;
height: 440px;
border-radius: 18px;
cursor: pointer;
overflow: hidden;
background: radial-gradient(circle at 50% 40%, #0e2236, #060d16);
border: 1px solid rgba(60,180,255,0.18);
}
.card-29__card::before {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 2px solid rgba(80,200,255,0.7);
box-shadow: 0 0 30px rgba(80,200,255,0.5);
z-index: 1;
}
.card-29__card:hover::before {
animation: card-29-ring 0.9s cubic-bezier(0.2,0.6,0.3,1) forwards;
}
@keyframes card-29-ring {
0% {
transform: translate(-50%,-50%) scale(0);
opacity: 0.9;
}
100% {
transform: translate(-50%,-50%) scale(60);
opacity: 0;
}
}
.card-29__card::after {
content: "";
position: absolute;
top: var(--card-29-y);
left: var(--card-29-x);
width: 10px;
height: 10px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
border: 1px solid rgba(160,90,255,0.6);
z-index: 1;
}
.card-29__card:hover::after {
animation: card-29-ring 1.1s cubic-bezier(0.2,0.6,0.3,1) 0.12s forwards;
}
.card-29__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #dceaf7;
}
.card-29__tag {
font-family: 'Chakra Petch', sans-serif;
font-size: 0.72rem;
letter-spacing: 0.24em;
text-transform: uppercase;
color: #4fc3ff;
}
.card-29__title {
font-family: 'Chakra Petch', sans-serif;
font-weight: 700;
font-size: 2.6rem;
line-height: 0.95;
}
.card-29__desc {
font-size: 0.86rem;
line-height: 1.6;
color: #8fa6bb;
}
.card-29__btn {
align-self: flex-start;
font-family: 'Chakra Petch', sans-serif;
font-size: 0.85rem;
letter-spacing: 0.06em;
padding: 0.7rem 1.5rem;
border-radius: 8px;
border: 1px solid rgba(80,200,255,0.4);
color: #4fc3ff;
background: rgba(80,200,255,0.08);
transition: background 0.3s ease;
}
.card-29__card:hover .card-29__btn {
background: rgba(80,200,255,0.18);
}
@media (prefers-reduced-motion: reduce) {
.card-29__card::before,
.card-29__card::after {
animation: none !important;
}
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.card-29');
if (!root) return;
const c = root.querySelector('[data-card-29="root"]');
if (!c) return;
c.addEventListener('mouseenter', (e) => {
const r = c.getBoundingClientRect();
c.style.setProperty('--card-29-x', `${e.clientX - r.left}px`);
c.style.setProperty('--card-29-y', `${e.clientY - r.top}px`);
});
})();
```How this works
A short JS handler listens for pointerenter on the card. On enter, it spawns a burst of expanding concentric rings — each a pseudo-element or dynamically-created div that scales from 0 to a target size and fades from opaque to transparent.
The rings sit behind the card content via a lower z-index. Their transform: scale() combined with opacity transitions is GPU-only — no reflow, no layout cost.
Multiple rings spawn with staggered delays (0ms, 100ms, 200ms) so the effect reads as a wave propagating outward rather than a single ring expanding.
Make it yours
- Tune wave count — 1 ring for restrained, 3-5 for full shockwave.
- Adjust ring size and speed — larger scale target and shorter duration read as pronounced impact; smaller and slower reads as calm ripple.
- Rebrand ring colour from
--shockwaveon.card-29. - Change stagger — instant simultaneous burst (0ms all) reads as impact; long delays (500ms) read as breathing.
- Add a matching subtle card shake or brightness pulse to the card itself alongside the rings.
Gotchas — read before shipping
- Under
prefers-reduced-motion, skip the wave spawn entirely — sudden expanding rings can trigger vestibular reactions. - The rings must have
pointer-events: noneso they don't intercept card clicks. - Clean up spawned ring elements on animation-end — leaving them in the DOM accumulates hundreds of dead nodes on repeated hovers.
- Cap the effect to trigger on
pointerenternotmouseover— pointerenter fires once per entry, mouseover fires on every child transition. - The visual burst is decorative — ensure the card's content and CTAs remain fully keyboard-focusable and screen-reader-readable.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 55+ | 13+ | 59+ | 55+ |
PointerEvent, CSS transitions, and transforms are universally supported. Older Safari and Firefox lack full pointer event support but degrade to mouseenter.