Skip to content
Textlab
1
Browse

ComponentsReveal

Blur reveal

Words sharpen into focus.

Make every word count

Installation

$ npx shadcn@latest add @textlab/blur-reveal

Needs @textlab in your components.json. Setup takes a minute.

Usage

usage.tsx
import { BlurReveal } from "@/components/textlab/blur-reveal/blur-reveal";

<BlurReveal as="h2" text="Make every word count" />

Variants

wordcharline

Props

PropTypeDefaultDescription
text*string–The copy.
variant"word" | "char" | "line""word"What sharpens on its own: each word, each letter or each measured line.
blurnumber12Starting blur in px.
asElementType"span"Rendered element.
trigger"mount" | "inView" | "hover" | "manual""inView"What starts the animation. manual follows `active`.
oncebooleantrueIn view: play once instead of on every entry.
delaynumber0Seconds before the first part moves.
staggernumber0.06 (word), 0.02 (char), 0.1 (line)Seconds between parts.
durationnumber0.8Seconds each part takes.
easeEaseName | [number, number, number, number]"enter"Easing token or cubic bezier.
reducedMotion"user" | "always" | "never""user"user follows the OS setting; always shows the still version.
classNamestring–Merged onto the root.
onComplete() => void–Called when a one-shot animation finishes.

When to use it

Reach for it

  • Hero and section titles that should feel calm and deliberate.
  • Short lines of copy, up to two sentences.

Skip it

  • Body paragraphs. Use scroll-fill for long copy that follows the reader.
  • Labels that change often. Use text-morph.

Accessibility and motion

Accessibility

  • The full text is in a visually hidden span; the animated parts are aria-hidden.
  • Keeps the heading tag you pass with as.

Motion

  • Triggers when 45% of the element is visible.
  • Opacity leads, blur clears next, the rise settles last.
Reduced motion. Shows the text immediately with no blur or movement.

Performance

  • Animates opacity, filter and transform only.
  • Blur is the costliest part; keep char variant under ~80 letters.