🔮

Magnetic Button Effect

A button that magnetically attracts itself towards the cursor when hovered using JavaScript mouse position tracking and CSS transforms.

buttonmagnetichoverinteractivemouse

Magnetic Button Effect — CSS & JavaScript Animation with Source Code

The Magnetic Button is a premium hover interaction where the button physically moves toward the user’s cursor as they hover near it, creating a magnetic attraction feeling. This effect is widely used on high-end agency websites and design portfolios. It uses vanilla JavaScript to track the cursor’s position relative to the button’s center and applies CSS transform: translate() proportionally.

How It Works

A mousemove event listener on the button calls getBoundingClientRect() to get the button’s position and dimensions. The cursor’s offset from the button’s center is calculated as x = clientX - rect.left - width/2 and y = clientY - rect.top - height/2. These values are scaled down (multiplied by 0.28 for the button, 0.15 for the inner text) and applied as transform: translate(xpx, ypx). On mouseleave, the transform resets to empty string, triggering the CSS transition back to origin.

Use Cases

  • Call-to-action buttons on landing pages
  • Navigation items on premium agency or portfolio sites
  • Interactive menu items and pill buttons
  • Icon buttons with subtle depth cues

How to Customize

  • Increase magnetic pull: Increase the multiplier from 0.28 to 0.45 or higher
  • Change button shape: Remove border-radius: 100px for a square button
  • Add a fill animation on hover: The .mag-btn:hover CSS already handles background/color change — customize these values
  • Add a ripple on click: Append a ripple <span> element on click events with a CSS keyframe scale animation

Frequently Asked Questions

Why does the button text move less than the button itself?

The inner .mag-text span uses a 0.15 multiplier compared to the button’s 0.28. This creates a parallax effect where the text lags slightly behind the button motion, adding depth and a premium feel. Both travel in the same direction.

Why must .mag-text have pointer-events: none?

Without this, hovering over the text element fires mouseleave on the button (since it’s technically a child boundary), causing jitter. Setting pointer-events: none makes the text invisible to mouse events so all events pass through to the parent button.

Does this work on touchscreens?

mousemove does not fire on touch devices. The button will display its static styles without movement, which is the correct graceful degradation. No broken behavior occurs on mobile.

Related Animations

Built by

Lawanya Chaudhari - Software Developer

Lawanya Chaudhari

Software Developer

I'm a Software Developer specializing in Angular, JavaScript, and TypeScript. I have a strong passion for building performant, user-friendly applications and developer tools that enhance productivity.

Code is like humor. When you have to explain it, it’s bad.