shadcn.io is not affiliated with official shadcn/ui
Kerning Text opens a little space around the letter under the pointer: its neighbours step aside, the next ones a little less, and they close up again as the pointer moves on, so a gap slides through the word with the pointer. The word keeps its width, so nothing around it moves.
Use it for a typographic headline: a type foundry's specimen, a designer's name, an editorial title. To thicken letters instead, use Variable Proximity; to pull them towards the pointer, Magnet Text; to fade them away, Erase Text. It's CSS only: each letter knows from :hover, + and :has() which side of the hovered letter it's on and how far, and a CSS utility the install adds to your stylesheet moves it with translate. There's no JavaScript at all.
Installation
Usage
import { KerningText } from "@/components/ui/kerning-text";<h1 className="uppercase">
<KerningText text="Typography" />
</h1>Demos
Intensity
intensity is how far the letters beside the pointer step away: subtle, medium, the default, or strong for a wide gap.
Link
Inside a link or a button, keyboard focus tracks every word out a little from 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 in right-to-left text the letters part the right way round. The gap only opens where the device can hover, so a tap never leaves letters apart. With reduced motion the letters step aside without easing.
FAQ
Does it need JavaScript?
No. Each letter matches selectors such as :hover + * (right after the hovered letter) and :has(+ :hover) (right before it), each setting its own CSS variable, and the utility turns those into a translate. It works before any script has loaded.
Why does the gap stay inside one word?
Each word is kept whole on its line, so a letter can only see its neighbours in the same word. The word's first and last letters step half as far, so the spaces between words stay spaces.
Does it change the width of the line?
No. The letters move with translate, which never changes the layout: the letters beside the pointer step away and the next ones close in a little to make room, so the word keeps its width.
What happens on a touch screen?
Nothing moves: the gap opens only on devices with a pointer that can hover, so the text simply reads as it is.
API Reference
KerningText
<span> data-slot="kerning-text"
textstring
The text.
intensity?"subtle" | "medium" | "strong"
How far the letters beside the pointer move apart: subtle,
medium, or strong for a wide gap.
- Type
"subtle" | "medium" | "strong"- Default
"medium"
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.
--kerning-text-spreadstring
How far a letter beside the pointer moves (0.14em).
Related
- Pro
Text Pressure
InteractiveA word that swells across its column
- Pro
Variable Proximity
InteractiveLetters thicken near the pointer
- Pro
Magnet Text
InteractiveLetters pulled in, not pushed apart
- Pro
Turn it over
Tilt Text
InteractiveThe whole word tilts toward the pointer
- Pro
Magnify Text
InteractiveA lens that enlarges what's under it
- Pro
Smallcaps Text
DecorativeA quiet change of type on hover