Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Text

Pro

Elastic Text for React

Text made of rubber: letters near the pointer stretch towards it and spring back with a wobble. For React with Base UI, when a headline should feel playful under the pointer.

Framework

Elastic Text makes letters behave like rubber. Near the pointer they stretch towards it, taller and thinner, each by its own distance, anchored on the far side as if the pointer were pulling them. As it moves on they spring back with a wobble, past their rest and back again, before they settle.

Use it for a playful headline: a toy, a game, a kids' app, a creative studio. To move letters towards the pointer without stretching them, use Magnet Text; for a jiggle that never stops, Wobble 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 stretch from its distance. The spring is a CSS linear() easing traced from a damped spring, on a CSS transition: no physics library and no frame loop.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { ElasticText } from "@/components/ui/elastic-text";
<h1>
  <ElasticText text="Stretchy" />
</h1>

Demos

Intensity

intensity is how far a letter under the pointer stretches: subtle to 1.15 times its height, medium, the default, to 1.35, and strong to 1.6. radius is how far from the pointer letters stretch, 100 pixels by default.

Preview width

Inside a link or a button, keyboard focus stretches every letter a little, a still state that needs no pointer.

Preview width

Accessibility

Screen readers read the text once, from a visually hidden copy, never letter by letter. Letters only grow taller and thinner, never wider, so they never run into each other; at strong the tallest can reach into the line above, so keep it for one-line headlines. With reduced motion the letters still stretch with the pointer, without the spring.

FAQ

How does it spring without a physics library?

The transition's easing is a linear() curve traced from a damped spring: it overshoots its rest by about a quarter, swings back by a twelfth, then settles, all within 900 ms. Every change of stretch rides that curve, so letters wobble back into shape.

Can I drag the letters?

No. Dragging would fight scrolling on a touch screen and clicks on a link around the text, so the letters answer the pointer passing over them instead.

Do the letters run into each other?

No. A stretched letter gets thinner as it gets taller, like rubber, so it never reaches its neighbours; the wobble widens it by a few per cent at most as it springs back.

How is it different from Magnet Text?

Magnet Text moves whole letters, rigid, towards the pointer. Elastic Text leaves each letter in place and stretches it, then lets it spring back with a wobble.

What happens on a touch screen?

A tap stretches the letters around it, and they spring back when the finger lifts.

What happens with reduced motion?

The letters still stretch towards the pointer, since that only answers what you do, but they go straight there and back, without the wobble.

API Reference

ElasticText

<span> data-slot="elastic-text"

PropType
textstring

The text.

intensity?"subtle" | "medium" | "strong"

How far a letter under the pointer stretches: subtle, medium, or strong for rubber.

Type
"subtle" | "medium" | "strong"
Default
"medium"
radius?number

How far from the pointer letters stretch, in pixels. @default 100.

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.

CSS variableType
--elastic-text-maxstring

A letter's height under the pointer, as a share of its own (1.35).

--elastic-text-radiusstring

How far letters stretch, in pixels, unitless (100).

All 97 text effects