shadcn.io is not affiliated with official shadcn/ui
Variable Proximity thickens each letter as the pointer comes near it: the letter right under the pointer is at its heaviest and the weight fades with distance, so a bold patch follows the pointer through the text. When the pointer leaves, every letter eases back to rest.
Use it for a large headline or a word on a landing page that invites the pointer over it. To light letters up rather than thicken them, use Spotlight Text; to swell a display word across its column, Text Pressure; to push letters apart, 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 weight from its distance, with no animation frame loop.
Installation
Usage
import { VariableProximity } from "@/components/ui/variable-proximity";<VariableProximity text="Bring the pointer closer" />Demos
Falloff
falloff is how the weight fades between the pointer and radius: linear evenly, quadratic sharply, with only the nearest letters heavy, and smooth in a soft bell with a wide peak.
Range
minWeight is the weight at rest and maxWeight the weight under the pointer, any weights your font has; radius is how far the pointer reaches, in pixels.
Accessibility
Screen readers read the text once, from a visually hidden copy, never letter by letter. The effect only follows the pointer and changes no meaning, so keyboard and touch users miss nothing. Every letter keeps the width of its heaviest weight, so the text never reflows under the pointer; with reduced motion the weight follows the pointer without easing.
FAQ
Which font does it need?
A variable font with a weight axis, such as Inter, Geist, Hanken Grotesk or Roboto Flex, for the weight to change smoothly. With a static font the weights snap to the ones you've loaded, usually just regular and bold.
Can it change slant or another axis too?
Each letter's nearness, from 0 at the radius to 1 under the pointer, is the --variable-proximity-t variable on its .variable-proximity-glyph, so your stylesheet can drive any axis from it: .variable-proximity-glyph { font-variation-settings: "slnt" calc(-10 * var(--variable-proximity-t)); }. An axis that widens letters, such as wdth, will shift the line.
Why is the text a little wider than usual?
Each letter holds the width of its heaviest weight, so the line doesn't shift as letters thicken. A smaller maxWeight keeps it closer to its usual spacing.
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 weight in CSS. Nothing runs while the pointer is elsewhere.
API Reference
VariableProximity
<span> data-slot="variable-proximity"
textstring
The text.
falloff?"linear" | "quadratic" | "smooth"
How the weight fades with distance: evenly, sharply near the pointer
(quadratic), or in a soft bell with a wide peak (smooth).
- Type
"linear" | "quadratic" | "smooth"- Default
"linear"
maxWeight?number
The weight right under the pointer. @default 900.
minWeight?number
The weight at rest, beyond the radius. @default 400.
radius?number
How far from the pointer letters are reached, in pixels. @default 120.
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.
--variable-proximity-maxstring
The weight under the pointer (900).
--variable-proximity-minstring
The weight at rest (400).
--variable-proximity-radiusstring
How far letters are reached, in pixels, unitless (120).
Related
- Pro
Every detail deserves the spotlightEvery detail deserves the spotlight
Spotlight Text
InteractiveLight the letters rather than thicken
- Pro
Text Pressure
InteractiveA word that swells across its column
- Pro
Magnify Text
InteractiveA lens that enlarges the letters
- Pro
Kerning Text
InteractiveLetters pushed apart near the pointer
- Pro
Erase Text
InteractiveLetters that fade under the pointer
- Pro
Magnet Text
InteractiveLetters pulled toward the pointer