Magnetic Button React component
A button that's pulled toward the pointer as it comes near, with its label drifting a little further for depth, a fill that sweeps in from the side you entered, and a springy wobble back into place when you move away.
About the Magnetic Button component
Magnetic Button leans toward your pointer as it gets close, as if pulled by a magnet, and its label drifts a little further than the button itself so it feels like it has depth. Move away and it springs back with a soft wobble.
It can also sweep a fill colour in from whichever side you came from, flipping the label colour to stay readable. It's a real button or link underneath, so keyboard and screen-reader use are unchanged.
When to use it
Use it for the one or two calls to action you want people to reach for — 'Get in touch', 'Start a project', social links — on portfolios, agency sites and launch pages.
Skip it for dense toolbars and forms: buttons that move are fun for a hero, tiring in a list of twenty.
Installation
Add the Magnetic Button component to your project with the shadcn CLI. It lands in components/magnetic-button.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/magnetic-buttonOr copy the source by hand and install its dependencies:
npm install clsx tailwind-mergeProps
<MagneticButton /> accepts 9 props (required ones are marked *).
| Prop | Type | Default |
|---|---|---|
| children* | React.ReactNode | — |
| strength How strongly the button follows the pointer (0–1). | number | 0.4 |
| radius How far outside the button the pull starts, in px. | number | 70 |
| labelDepth How much further the label moves than the button, for a sense of depth. | number | 0.5 |
| bounce Springiness of the return: 0 = no overshoot, 1 = wobbly. | number | 0.5 |
| fill Fill circle that grows from the pointer on hover. | string | — |
| fillText Label colour while the fill covers the button. | string | — |
| className | string | — |
| labelClassName | string | — |
- children*React.ReactNode
- strength
How strongly the button follows the pointer (0–1).
numberDefault: 0.4 - radius
How far outside the button the pull starts, in px.
numberDefault: 70 - labelDepth
How much further the label moves than the button, for a sense of depth.
numberDefault: 0.5 - bounce
Springiness of the return: 0 = no overshoot, 1 = wobbly.
numberDefault: 0.5 - fill
Fill circle that grows from the pointer on hover.
string - fillText
Label colour while the fill covers the button.
string - classNamestring
- labelClassNamestring
npm dependencies
Installed for you by the shadcn CLI.
Magnetic Button FAQ
- How strong is the pull?
- strength (0–1) is the share of the distance to the pointer the button travels; radius is how far outside the button the pull begins. bounce sets how much it overshoots on the way back.
- Can it be a link?
- Yes. Pass href and it renders an <a>; otherwise it's a <button> that takes every native button prop.
- How does the fill work?
- Set fill to a colour and a circle grows from the point the pointer entered; fillText sets the label colour while it's filled.
- Does it move on phones?
- No. The pull only follows a mouse, and it's off entirely with reduced motion turned on; the button works normally either way.