33 CSS Card Hover Effects23 / 33
Magnetic Float
A music/interactive card with a glowing orb that leans toward the cursor as if caught in a magnetic field, over a tech grid backdrop. Ideal for interactive demos, audio apps, and playful CTAs that invite the pointer in.
Published Updated
The code
<div class="card-23">
<article class="card-23__card" data-card-23="root">
<div class="card-23__grid"></div>
<div class="card-23__orb" data-card-23="orb">PLAY ▶</div>
<div class="card-23__inner">
<span class="card-23__eyebrow">Interactive Demo</span>
<h2 class="card-23__title">Gravity<br>Synth</h2>
<p class="card-23__desc">Drag your cursor near the orb — it leans toward you like it's caught in your field.</p>
</div>
</article>
</div><div class="card-23">
<article class="card-23__card" data-card-23="root">
<div class="card-23__grid"></div>
<div class="card-23__orb" data-card-23="orb">PLAY ▶</div>
<div class="card-23__inner">
<span class="card-23__eyebrow">Interactive Demo</span>
<h2 class="card-23__title">Gravity<br>Synth</h2>
<p class="card-23__desc">Drag your cursor near the orb — it leans toward you like it's caught in your field.</p>
</div>
</article>
</div>@import url('https://fonts.googleapis.com/css2?family=Unbounded:wght@500;700;900&family=Manrope:wght@400;500;700&display=swap');
.card-23,
.card-23 *,
.card-23 *::before,
.card-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-23 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #06060a;
font-family: 'Manrope', sans-serif;
padding: 2rem;
}
.card-23__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 26px;
background: radial-gradient(circle at 50% 0%, #1c2540, #0a0d1a);
cursor: pointer;
overflow: hidden;
border: 1px solid rgba(120,160,255,0.12);
}
.card-23__grid {
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(120,160,255,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(120,160,255,0.06) 1px, transparent 1px);
background-size: 28px 28px;
}
.card-23__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e9eefc;
}
.card-23__eyebrow {
font-size: 0.72rem;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #6f8bd6;
}
.card-23__title {
font-family: 'Unbounded', sans-serif;
font-weight: 700;
font-size: 2.1rem;
line-height: 1.05;
}
.card-23__desc {
font-size: 0.85rem;
line-height: 1.6;
color: #93a0c4;
}
.card-23__orb {
position: absolute;
top: 50%;
left: 50%;
width: 110px;
height: 110px;
margin: -55px 0 0 -55px;
border-radius: 50%;
background: linear-gradient(145deg, #6a8cff, #b46aff);
display: grid;
place-items: center;
color: #fff;
font-weight: 700;
font-size: 0.95rem;
letter-spacing: 0.05em;
z-index: 3;
box-shadow: 0 0 40px rgba(120,140,255,0.5);
transition: transform 0.18s ease-out, box-shadow 0.3s ease;
will-change: transform;
}
.card-23__card:hover .card-23__orb {
box-shadow: 0 0 60px rgba(140,120,255,0.7);
}
@media (prefers-reduced-motion: reduce) {
.card-23__orb {
transition: none !important;
}
}@import url('https://fonts.googleapis.com/css2?family=Unbounded:wght@500;700;900&family=Manrope:wght@400;500;700&display=swap');
.card-23,
.card-23 *,
.card-23 *::before,
.card-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-23 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #06060a;
font-family: 'Manrope', sans-serif;
padding: 2rem;
}
.card-23__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 26px;
background: radial-gradient(circle at 50% 0%, #1c2540, #0a0d1a);
cursor: pointer;
overflow: hidden;
border: 1px solid rgba(120,160,255,0.12);
}
.card-23__grid {
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(120,160,255,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(120,160,255,0.06) 1px, transparent 1px);
background-size: 28px 28px;
}
.card-23__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e9eefc;
}
.card-23__eyebrow {
font-size: 0.72rem;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #6f8bd6;
}
.card-23__title {
font-family: 'Unbounded', sans-serif;
font-weight: 700;
font-size: 2.1rem;
line-height: 1.05;
}
.card-23__desc {
font-size: 0.85rem;
line-height: 1.6;
color: #93a0c4;
}
.card-23__orb {
position: absolute;
top: 50%;
left: 50%;
width: 110px;
height: 110px;
margin: -55px 0 0 -55px;
border-radius: 50%;
background: linear-gradient(145deg, #6a8cff, #b46aff);
display: grid;
place-items: center;
color: #fff;
font-weight: 700;
font-size: 0.95rem;
letter-spacing: 0.05em;
z-index: 3;
box-shadow: 0 0 40px rgba(120,140,255,0.5);
transition: transform 0.18s ease-out, box-shadow 0.3s ease;
will-change: transform;
}
.card-23__card:hover .card-23__orb {
box-shadow: 0 0 60px rgba(140,120,255,0.7);
}
@media (prefers-reduced-motion: reduce) {
.card-23__orb {
transition: none !important;
}
}(() => {
const root = document.querySelector('.card-23');
if (!root) return;
const card = root.querySelector('[data-card-23="root"]');
const orb = root.querySelector('[data-card-23="orb"]');
if (!card || !orb) return;
card.addEventListener('mousemove', (e) => {
const r = card.getBoundingClientRect();
const cx = r.left + r.width / 2;
const cy = r.top + r.height / 2;
const dx = (e.clientX - cx) * 0.4;
const dy = (e.clientY - cy) * 0.4;
orb.style.transform = `translate(${dx}px, ${dy}px) scale(1.05)`;
});
card.addEventListener('mouseleave', () => {
orb.style.transform = 'translate(0,0) scale(1)';
});
})();(() => {
const root = document.querySelector('.card-23');
if (!root) return;
const card = root.querySelector('[data-card-23="root"]');
const orb = root.querySelector('[data-card-23="orb"]');
if (!card || !orb) return;
card.addEventListener('mousemove', (e) => {
const r = card.getBoundingClientRect();
const cx = r.left + r.width / 2;
const cy = r.top + r.height / 2;
const dx = (e.clientX - cx) * 0.4;
const dy = (e.clientY - cy) * 0.4;
orb.style.transform = `translate(${dx}px, ${dy}px) scale(1.05)`;
});
card.addEventListener('mouseleave', () => {
orb.style.transform = 'translate(0,0) scale(1)';
});
})();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: Magnetic Float
Source: https://codefronts.com/motion/css-card-hover-effects/magnetic-float/
A music/interactive card with a glowing orb that leans toward the cursor as if caught in a magnetic field, over a tech grid backdrop. Ideal for interactive demos, audio apps, and playful CTAs that invite the pointer in.
## HTML
```html
<div class="card-23">
<article class="card-23__card" data-card-23="root">
<div class="card-23__grid"></div>
<div class="card-23__orb" data-card-23="orb">PLAY ▶</div>
<div class="card-23__inner">
<span class="card-23__eyebrow">Interactive Demo</span>
<h2 class="card-23__title">Gravity<br>Synth</h2>
<p class="card-23__desc">Drag your cursor near the orb — it leans toward you like it's caught in your field.</p>
</div>
</article>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Unbounded:wght@500;700;900&family=Manrope:wght@400;500;700&display=swap');
.card-23,
.card-23 *,
.card-23 *::before,
.card-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-23 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #06060a;
font-family: 'Manrope', sans-serif;
padding: 2rem;
}
.card-23__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 26px;
background: radial-gradient(circle at 50% 0%, #1c2540, #0a0d1a);
cursor: pointer;
overflow: hidden;
border: 1px solid rgba(120,160,255,0.12);
}
.card-23__grid {
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(120,160,255,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(120,160,255,0.06) 1px, transparent 1px);
background-size: 28px 28px;
}
.card-23__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e9eefc;
}
.card-23__eyebrow {
font-size: 0.72rem;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #6f8bd6;
}
.card-23__title {
font-family: 'Unbounded', sans-serif;
font-weight: 700;
font-size: 2.1rem;
line-height: 1.05;
}
.card-23__desc {
font-size: 0.85rem;
line-height: 1.6;
color: #93a0c4;
}
.card-23__orb {
position: absolute;
top: 50%;
left: 50%;
width: 110px;
height: 110px;
margin: -55px 0 0 -55px;
border-radius: 50%;
background: linear-gradient(145deg, #6a8cff, #b46aff);
display: grid;
place-items: center;
color: #fff;
font-weight: 700;
font-size: 0.95rem;
letter-spacing: 0.05em;
z-index: 3;
box-shadow: 0 0 40px rgba(120,140,255,0.5);
transition: transform 0.18s ease-out, box-shadow 0.3s ease;
will-change: transform;
}
.card-23__card:hover .card-23__orb {
box-shadow: 0 0 60px rgba(140,120,255,0.7);
}
@media (prefers-reduced-motion: reduce) {
.card-23__orb {
transition: none !important;
}
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.card-23');
if (!root) return;
const card = root.querySelector('[data-card-23="root"]');
const orb = root.querySelector('[data-card-23="orb"]');
if (!card || !orb) return;
card.addEventListener('mousemove', (e) => {
const r = card.getBoundingClientRect();
const cx = r.left + r.width / 2;
const cy = r.top + r.height / 2;
const dx = (e.clientX - cx) * 0.4;
const dy = (e.clientY - cy) * 0.4;
orb.style.transform = `translate(${dx}px, ${dy}px) scale(1.05)`;
});
card.addEventListener('mouseleave', () => {
orb.style.transform = 'translate(0,0) scale(1)';
});
})();
```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: Magnetic Float
Source: https://codefronts.com/motion/css-card-hover-effects/magnetic-float/
A music/interactive card with a glowing orb that leans toward the cursor as if caught in a magnetic field, over a tech grid backdrop. Ideal for interactive demos, audio apps, and playful CTAs that invite the pointer in.
## HTML
```html
<div class="card-23">
<article class="card-23__card" data-card-23="root">
<div class="card-23__grid"></div>
<div class="card-23__orb" data-card-23="orb">PLAY ▶</div>
<div class="card-23__inner">
<span class="card-23__eyebrow">Interactive Demo</span>
<h2 class="card-23__title">Gravity<br>Synth</h2>
<p class="card-23__desc">Drag your cursor near the orb — it leans toward you like it's caught in your field.</p>
</div>
</article>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Unbounded:wght@500;700;900&family=Manrope:wght@400;500;700&display=swap');
.card-23,
.card-23 *,
.card-23 *::before,
.card-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-23 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #06060a;
font-family: 'Manrope', sans-serif;
padding: 2rem;
}
.card-23__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 26px;
background: radial-gradient(circle at 50% 0%, #1c2540, #0a0d1a);
cursor: pointer;
overflow: hidden;
border: 1px solid rgba(120,160,255,0.12);
}
.card-23__grid {
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(120,160,255,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(120,160,255,0.06) 1px, transparent 1px);
background-size: 28px 28px;
}
.card-23__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e9eefc;
}
.card-23__eyebrow {
font-size: 0.72rem;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #6f8bd6;
}
.card-23__title {
font-family: 'Unbounded', sans-serif;
font-weight: 700;
font-size: 2.1rem;
line-height: 1.05;
}
.card-23__desc {
font-size: 0.85rem;
line-height: 1.6;
color: #93a0c4;
}
.card-23__orb {
position: absolute;
top: 50%;
left: 50%;
width: 110px;
height: 110px;
margin: -55px 0 0 -55px;
border-radius: 50%;
background: linear-gradient(145deg, #6a8cff, #b46aff);
display: grid;
place-items: center;
color: #fff;
font-weight: 700;
font-size: 0.95rem;
letter-spacing: 0.05em;
z-index: 3;
box-shadow: 0 0 40px rgba(120,140,255,0.5);
transition: transform 0.18s ease-out, box-shadow 0.3s ease;
will-change: transform;
}
.card-23__card:hover .card-23__orb {
box-shadow: 0 0 60px rgba(140,120,255,0.7);
}
@media (prefers-reduced-motion: reduce) {
.card-23__orb {
transition: none !important;
}
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.card-23');
if (!root) return;
const card = root.querySelector('[data-card-23="root"]');
const orb = root.querySelector('[data-card-23="orb"]');
if (!card || !orb) return;
card.addEventListener('mousemove', (e) => {
const r = card.getBoundingClientRect();
const cx = r.left + r.width / 2;
const cy = r.top + r.height / 2;
const dx = (e.clientX - cx) * 0.4;
const dy = (e.clientY - cy) * 0.4;
orb.style.transform = `translate(${dx}px, ${dy}px) scale(1.05)`;
});
card.addEventListener('mouseleave', () => {
orb.style.transform = 'translate(0,0) scale(1)';
});
})();
```How this works
The card sits still at rest. A vanilla JS handler tracks the pointer's proximity to the card's centre: on every mousemove, it calculates the pointer's distance from the card and, if within a “magnetic radius” (usually the card's bounding box + 40px), pulls the card toward the pointer.
The handler writes translate3d(x, y, 0) values to the card's inline style. As the pointer approaches, the offsets grow proportionally to how close the pointer gets — like an invisible magnet field.
On mouseleave, the offsets reset via a spring transition — the card overshoots slightly before settling back to origin.
Make it yours
- Tune magnetic strength — multiply the pointer offset by 0.15 (subtle), 0.3 (medium), or 0.5 (strong).
- Adjust the magnetic radius — smaller radius only pulls when pointer is very close; larger radius reads as gravitational.
- Rebrand the card body from
--card-bgand--card-fgon.card-23. - Change spring feel on reset by tuning the cubic-bezier —
cubic-bezier(0.34, 1.56, 0.64, 1)for overshoot, ease-out for smooth. - Add a matching magnetic shadow — the shadow offset follows the pointer independently for a “light source” feel.
Gotchas — read before shipping
- Throttle mousemove with
requestAnimationFrame— heavy transform updates every raw event drops framerate. - Guard with
@media (hover: hover) and (pointer: fine)— touch devices don't have a magnetic pointer field. - Under
prefers-reduced-motion, skip the follow behaviour and use a small static lift on hover instead. - Reset the transform on
mouseleave, not onmouseout— mouseout fires on inner elements and produces jitter. - The magnetic pull is decorative — every clickable element needs its own
:focus-visiblering.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 36+ | 9+ | 16+ | 36+ |
Vanilla JS pointer events, transforms, and cubic-bezier transitions are universally supported. No polyfills needed.