Liquid Text React component
Text distorted through an animated SVG noise filter, 5 presets (liquid, melt, blob, ghost, crystal), cursor-proximity intensity, and a click burst ripple.
About the Liquid Text component
Liquid Text is a free effect that runs real DOM text through an animated SVG filter. Fractal noise drives a displacement map, so the letters ripple, melt or wobble continuously. Moving the pointer toward the center strengthens the distortion, and an optional click burst spikes it for three quarters of a second.
preset sets the character of the effect: liquid, melt (stretches vertically), blob (thickened, softened edges), ghost (heavier blur) or crystal (sharper turbulence). scaleMultiplier scales the whole distortion, mouseEnabled, mouseStrength and mouseRadius tune the pointer boost, and clickBurst with burstStrength adds the tap effect. The text takes fontSize or autoFit, fontWeight, fontFamily, letterSpacing, and textColor or a gradient, and useGlow adds a glow in glowColor.
When to use it
Use it for a hero word, event or festival titles, music and drink brands, or anything with a water theme where a fluid look fits.
Keep it to a few large words, since the distortion makes small text hard to read. For a crisp 3D hover, use Tilt Text.
Installation
Add the Liquid Text component to your project with the shadcn CLI. It lands in components/liquid-text.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/liquid-textOr copy the source by hand and install its dependencies:
npm install clsx tailwind-mergeProps
<LiquidText /> accepts 22 props, all optional. It also accepts the usual <div> attributes, like className, style, id and aria-*, and passes them to its root element.
| Prop | Type | Default |
|---|---|---|
| text | string | "Liquid" |
| fontSize | number | 120 |
| autoFit | boolean | false |
| fitPadding | number | 5 |
| fontWeight | string | "700" |
| fontFamily | string | "Inter, sans-serif" |
| letterSpacing | number | -2 |
| textColor | string | "#87FFE3" |
| backgroundColor | string | "#000000" |
| useGradient | boolean | false |
| gradientColorTo | string | "#ff55ee" |
| gradientDirection | "horizontal" | "vertical" | "radial" | "horizontal" |
- textstringDefault: "Liquid"
- fontSizenumberDefault: 120
- autoFitbooleanDefault: false
- fitPaddingnumberDefault: 5
- fontWeightstringDefault: "700"
- fontFamilystringDefault: "Inter, sans-serif"
- letterSpacingnumberDefault: -2
- textColorstringDefault: "#87FFE3"
- backgroundColorstringDefault: "#000000"
- useGradientbooleanDefault: false
- gradientColorTostringDefault: "#ff55ee"
- gradientDirection"horizontal" | "vertical" | "radial"Default: "horizontal"
Show all 22 propsShow fewer
| preset | "liquid" | "melt" | "blob" | "ghost" | "crystal" | "liquid" |
| scaleMultiplier | number | 1 |
| mouseEnabled | boolean | true |
| mouseStrength | number | 2 |
| mouseRadius | number | 300 |
| clickBurst | boolean | false |
| burstStrength | number | 3 |
| useGlow | boolean | false |
| glowColor | string | "#87FFE3" |
| glowRadius | number | 20 |
- preset"liquid" | "melt" | "blob" | "ghost" | "crystal"Default: "liquid"
- scaleMultipliernumberDefault: 1
- mouseEnabledbooleanDefault: true
- mouseStrengthnumberDefault: 2
- mouseRadiusnumberDefault: 300
- clickBurstbooleanDefault: false
- burstStrengthnumberDefault: 3
- useGlowbooleanDefault: false
- glowColorstringDefault: "#87FFE3"
- glowRadiusnumberDefault: 20
Collections
Use-case pages that compare Liquid Text with the other components that do a similar job.
npm dependencies
Installed for you by the shadcn CLI.
Liquid Text FAQ
- Can screen readers still read the text?
- Yes. It is a normal span, and the filter only changes how it is painted. The SVG that holds the filter is aria-hidden.
- Can I use several on one page?
- Yes. Each instance builds its filter id from React's useId, so the filters don't collide.
- How do I calm it down?
- Lower scaleMultiplier (default 1) or use the liquid preset, and set mouseEnabled={false} so the cursor doesn't add distortion.
- Why is there space around the text?
- The filtered layer has 60px of padding so the displaced edges aren't clipped by the container.