Magnetic Button
Live Preview
DEMO COMMING SOON
Video Tutorial YouTube
Setup & Installation Guide
01 Add the HTML
Add your button and give it the data-magnetic attribute. You can apply this to any existing button — no class renaming required.
02 Add the CSS
Style the button however you like. The only rule is no CSS transition on transform — GSAP controls the position entirely.
03 Load GSAP + paste the script
Load GSAP from CDN before your script. Paste the JS snippet and it will auto-target every [data-magnetic] element on the page.
WORKING IN WEBFLOW
CDN
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script> <button class="mag-btn" data-magnetic>
<span class="mag-btn__text">Hover Me</span>
</button>
.mag-btn {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 24px 40px;
background-color: #ff4d1c;
border: none;
border-radius: 100px;
cursor: pointer;
color: #fff;
font-size: 18px;
font-weight: 500;
letter-spacing: 0.04em;
/* Do NOT add CSS transitions on transform — GSAP owns it */
}
.mag-btn__text {
pointer-events: none;
user-select: none;
}
// Magnetic Button — GSAP quickTo
// Requires: <script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
(function () {
const STRENGTH = 0.4;
document.querySelectorAll('[data-magnetic]').forEach((btn) => {
const xTo = gsap.quickTo(btn, 'x', { duration: 0.6, ease: 'power3.out' });
const yTo = gsap.quickTo(btn, 'y', { duration: 0.6, ease: 'power3.out' });
btn.addEventListener('mousemove', (e) => {
const rect = btn.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
xTo((e.clientX - centerX) * STRENGTH);
yTo((e.clientY - centerY) * STRENGTH);
});
btn.addEventListener('mouseleave', () => { xTo(0); yTo(0); });
});
})();
Explore More
Custom Cursor
Build a two-part custom cursor — a sharp inner dot and a lagging outer ring — using GSAP quickTo for silky 60fps tracking.
SplitText Hero Reveal
Split a hero heading into individual characters and animate them up through a line mask — no flash, no layout shift, works with custom fonts.