Buttons & Toggles

Magnetic Button

A magnetic button that is pulled towards the cursor as it approaches, with a parallax on the inner text and a spring back once the cursor leaves.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add magnetic-button.en

New project or installation trouble? Start here →

Magnetic Button is a React magnetic button component built with Tailwind CSS and Motion. As the mouse moves over it, the button shifts toward the cursor based on its distance from the center, the inner label moves half as far in the opposite direction, and a spring brings it back when the cursor leaves.

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

0.35
Active edited usageDefault props
<MagneticButton/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

When to use

  • The main call to action on a portfolio or creative studio site, such as "Contact us" or "View work".
  • The single CTA in a landing page hero, where the button should respond visibly to the cursor.
  • Contact sections in the footer or newsletter sign-up buttons.
  • Not a good fit: densely packed buttons such as table rows or toolbars, where the offset can make neighbors look like they overlap.

Installation

npx webberui@latest add https://webberui.com/r/magnetic-button.en.json

Installing also writes the --wb-duration-fast CSS variable into your global stylesheet.

Usage

import { MagneticButton } from "@/components/ui/magnetic-button";

<MagneticButton onClick={() => console.log("clicked")}>
  Get started
</MagneticButton>

Examples

Outline style

The default is a solid button. className merges with the default classes, so you can turn it into an outline button.

<MagneticButton className="border border-neutral-300 bg-transparent text-neutral-900 hover:bg-neutral-100 dark:border-neutral-700 dark:bg-transparent dark:text-neutral-100 dark:hover:bg-neutral-800">
  View work
</MagneticButton>

Tune the pull and the spring

A larger strength gives a bigger offset. springConfig takes Motion spring options; lowering damping makes the return wobble more.

<MagneticButton
  strength={0.5}
  springConfig={{ stiffness: 180, damping: 10, mass: 0.8 }}
  className="px-8 py-4 text-base"
>
  Book a consultation
</MagneticButton>

As a form submit button

The component defaults to type="button"; passing type="submit" overrides it. Other native attributes such as disabled are forwarded as well, and the magnetic effect turns off while disabled.

<form action={subscribe} className="flex gap-2">
  <input name="email" type="email" required placeholder="you@example.com" className="rounded-full border px-4" />
  <MagneticButton type="submit" disabled={pending}>
    Subscribe
  </MagneticButton>
</form>

Props

PropTypeDefaultDescription
strengthnumber0.35Magnet strength: the button's offset = the cursor's distance from center × strength; 0 means it does not move at all
springConfigSpringOptions{ stiffness: 260, damping: 18, mass: 0.7 }Spring parameters for the return after the cursor leaves
classNamestring—Overrides the default styles (a solid button by default, changeable to an outline or other variant)
childrenReactNode—Button content

All other <button> attributes (onClick, disabled, aria-*, and so on) are forwarded directly.

How it works

  • Parallax depth: as the button shifts towards the cursor, the inner text shifts half as far in the opposite direction, producing a two-layer sense of depth
  • Spring back: driven by useMotionValue + useSpring, so it springs back to its original position with momentum once the cursor leaves
  • Disabled on touch devices automatically: it only responds to mouse pointer events (pointerType === "mouse"), so on touch it is just an ordinary button
  • When the user has "reduce motion" enabled at the system level, the magnetism is disabled: the button stays put and functionality is unaffected
  • The magnetism is also disabled while disabled

FAQ

Does it work with the Next.js App Router?

Yes. The file starts with "use client", so import it from a Server Component page as usual.

How do I change the magnetic strength?

strength sets the offset: the button moves by the cursor's distance from its center multiplied by strength (default 0.35), and 0 disables movement. Tune the return feel with springConfig.

I also need onPointerMove. Will it be overridden?

No. The component calls your onPointerMove and onPointerLeave first, then runs its own magnetic logic.

What happens on phones and touch devices?

The effect only responds to mouse pointer events, so on touch it is a regular button. It is also turned off when the system "reduce motion" setting is on or the button is disabled.

What are the dependencies?

motion, clsx and tailwind-merge. If you prefer not to use the CLI, copy the source from the Manual tab in Installation.