shadcn.io is not affiliated with official shadcn/ui
Magnet Text pulls letters towards the pointer as it passes, each by its own distance, like iron filings near a magnet: letters below the pointer rise to meet it, letters above it dip, and along the line they tip and gather in around it. When the pointer leaves, they spring home with a little overshoot.
Use it for a headline, a name or a call to action that should feel alive under the pointer. To stretch letters towards the pointer instead of moving them, use Elastic Text; to thicken them, Variable Proximity; to part them, Kerning Text. The letters' centres are measured once as the pointer enters; each move writes the pointer's position to two CSS variables, and a CSS utility the install adds to your stylesheet works out each letter's translate and rotate from its offset to the pointer and its nearness, capped, and a CSS transition with a slight overshoot carries it there. There's no animation library and no frame loop.
Installation
Usage
import { MagnetText } from "@/components/ui/magnet-text";<h1>
<MagnetText text="Magnetic" />
</h1>Demos
Intensity
intensity is how hard the letters are pulled and the farthest they go: subtle for a twitch, medium, the default, for a headline, strong for letters that reach. radius is how far from the pointer letters feel the pull, 160 pixels by default.
Link
Inside a link or a button, keyboard focus draws each word's letters a little towards its middle, a still state that needs no pointer.
Accessibility
Screen readers read the text once, from a visually hidden copy, never letter by letter. Words wrap whole, and the line keeps its direction on a right-to-left page. Letters move by a fraction of their size, 0.15em and 10° at most by default, and never into each other, so the text stays readable while it moves. With reduced motion the letters still follow the pointer, without the spring.
FAQ
Why doesn't the letter under the pointer move?
It's already where the pointer is. Pulling the letters right beside the pointer hardest would crush them into each other, so along the line the pull and the tip are gentlest at the pointer and strongest a little way out; above and below the line, where letters can't collide, the nearest move most.
How far does the pull reach?
radius sets it, in pixels: letters farther from the pointer don't move. A larger radius makes a wide, gentle field; a smaller one a tight, quick one.
How is it different from Elastic Text?
Magnet Text moves whole letters, rigid, towards the pointer. Elastic Text leaves each letter in place and stretches it towards the pointer like rubber, then lets it spring back with a wobble.
Does it run on every frame?
No. It measures the letters once as the pointer comes over the text and then only writes the pointer's position on each move; the browser works out every letter's position in CSS. Nothing runs while the pointer is elsewhere.
API Reference
MagnetText
<span> data-slot="magnet-text"
textstring
The text.
intensity?"subtle" | "medium" | "strong"
How hard the letters are pulled, and the farthest they go: subtle
for a twitch, medium, or strong for letters that reach.
- Type
"subtle" | "medium" | "strong"- Default
"medium"
radius?number
How far from the pointer letters feel the pull, in pixels. @default 160.
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
--magnet-text-maxstring
The farthest a letter moves (0.15em).
--magnet-text-pullstring
How much of the way to the pointer a letter leans, 0 to 1 (0.25).
--magnet-text-radiusstring
How far letters feel the pull, in pixels, unitless (160).
Related
- Pro
Text Pressure
InteractiveLetters that swell and stretch instead
- Pro
Variable Proximity
InteractiveLetters thicken near the pointer
- Pro
Kerning Text
InteractiveLetters pushed apart, not pulled in
- Pro
Turn it over
Tilt Text
InteractiveThe word turns to face the pointer
- Pro
Elastic Text
InteractiveLetters stretch as the pointer passes
- Pro
Inertia Text
InteractiveThrow the whole word, it springs home