Back to library
INTERACTION_003

Magnetic Button.

The button tracks the cursor within a proximity radius, translating a fraction of the pointer offset and snapping home on exit. The single most stolen interaction on the internet.

CATEGORY
Buttons
COMPLEXITY
Intermediate
TECH
CSS + JS
PLATFORM
Desktop
PERFORMANCE
Light
LIVE PLAYGROUND
JavaScript / JS
const btn = document.querySelector(".magnetic");
const STRENGTH = 0.35;
let frame;

btn.addEventListener("pointermove", (e) => {
  cancelAnimationFrame(frame);
  frame = requestAnimationFrame(() => {
    const r = btn.getBoundingClientRect();
    const x = e.clientX - (r.left + r.width / 2);
    const y = e.clientY - (r.top + r.height / 2);
    btn.style.transform = `translate(${x * STRENGTH}px, ${y * STRENGTH}px)`;
  });
});

btn.addEventListener("pointerleave", () => {
  btn.style.transform = "translate(0, 0)";
});
React / TSX
export function MagneticButton({ children }: { children: React.ReactNode }) {
  const ref = useRef<HTMLButtonElement>(null);

  const onMove = (e: React.PointerEvent) => {
    const el = ref.current;
    if (!el || !window.matchMedia("(pointer: fine)").matches) return;
    const r = el.getBoundingClientRect();
    const x = (e.clientX - (r.left + r.width / 2)) * 0.35;
    const y = (e.clientY - (r.top + r.height / 2)) * 0.35;
    el.style.transform = `translate(${x}px, ${y}px)`;
  };

  return (
    <button
      ref={ref}
      onPointerMove={onMove}
      onPointerLeave={() => ref.current && (ref.current.style.transform = "")}
      className="rounded-full bg-white px-7 py-3.5 text-black transition-transform duration-500 ease-[cubic-bezier(0.22,1,0.36,1)]"
    >
      {children}
    </button>
  );
}

IF YOU LIKE THIS, STEAL THESE TOO.

MOVE INSIDE
INTERACTION_012CSS + JS

Custom Cursor

Dot plus trailing ring with contextual labels.

Mouse / MediumView
INTERACTION_004CSS

Sliding Arrow

Directional arrow that translates on hover.

Buttons / LightView
INTERACTION_001CSS

Premium Button Lift

Weightless 2px rise with an edge highlight on hover.

Buttons / LightView
INTERACTION_002CSS

Shine Sweep Button

A diagonal chrome glint travels across the surface on hover.

Buttons / LightView