Join our Discord Community

React Blur Text Animation

Text that animates from blur to focus with intersection observer. Perfect for React applications requiring elegant scroll-triggered text reveals.

Powered by

Trying to implement blur text animations?

Join our Discord community for help from other developers.


Most text animations are abrupt and mechanical—instant visibility changes that don't feel natural or engaging. This component creates smooth blur-to-focus transitions that animate text elements progressively, using CSS filter blur and intersection observer to trigger animations when content enters the viewport.

Progressive blur-to-focus text animation

Text that smoothly transitions from blurred to focused with staggered timing:

Loading component...

Built with TypeScript and Motion for React applications, using intersection observer for scroll-triggered animations. The component supports both word-by-word and letter-by-letter animation modes with customizable blur transitions and directional movement.

Installation

npx shadcn@latest add https://www.shadcn.io/registry/blur-text.json
npx shadcn@latest add https://www.shadcn.io/registry/blur-text.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/blur-text.json
bunx shadcn@latest add https://www.shadcn.io/registry/blur-text.json

Usage

import BlurText from "@/components/text/blur-text";

const handleAnimationComplete = () => {
  console.log('Animation completed!');
};

<BlurText
  text="Beautiful components that make React development a joy!"
  delay={150}
  animateBy="words"
  direction="top"
  onAnimationComplete={handleAnimationComplete}
  className="text-4xl font-bold"
/>

Why most text animations feel artificial

Most developers use simple opacity or transform changes—binary visibility states that don't capture the natural way focus works in real vision. When humans focus on text, there's a gradual clearing process that involves both sharpness and positional settling.

This React component uses CSS filter blur combined with opacity and transform animations to simulate natural focusing. The staggered timing creates a wave effect as text segments progressively come into focus, while the intersection observer ensures animations trigger at the optimal scroll position.

The key insight: natural focus is gradual and layered. When blur clears progressively while elements settle into position, it mirrors how human vision processes information, creating more intuitive and engaging text reveals.

Features

  • Intersection observer-triggered animations with configurable threshold and root margin settings
  • Word-by-word or letter-by-letter animation modes with independent timing controls
  • Multi-stage blur transitions with customizable keyframes for complex animation sequences
  • Directional movement support with top/bottom slide animations during blur clearing
  • Custom animation curves with Motion's easing system for precise timing control
  • Performance optimized with will-change properties and hardware acceleration
  • Free open source component compatible with Next.js and shadcn/ui design systems

API Reference

BlurText

Blur-to-focus text animation component with intersection observer.

PropTypeDefaultDescription
textstringrequiredText content to animate
delaynumber200Delay between element animations (ms)
animateBy'words' | 'letters''words'Animation granularity
direction'top' | 'bottom''top'Direction of movement during animation
thresholdnumber0.1Intersection observer threshold
rootMarginstring'0px'Intersection observer root margin
animationFromRecord<string, string | number>-Custom initial animation state
animationToArray<Record<string, string | number>>-Custom animation keyframes
easingEasing | Easing[](t) => tAnimation easing function
onAnimationComplete() => void-Callback when animation completes
stepDurationnumber0.35Duration of each animation step (s)
classNamestring-Additional CSS classes

Animation Timing Configuration

Control the animation flow with timing parameters:

SettingFastBalancedSlow
delay50ms150ms300ms
stepDuration0.2s0.35s0.5s

Intersection Observer Settings

Fine-tune when animations trigger:

SettingEarly TriggerBalancedLate Trigger
threshold0.1 (10% visible)0.3 (30% visible)0.7 (70% visible)
rootMargin'100px''0px''-50px'

Common gotchas

Animation doesn't trigger: Check that the component is properly mounted and the intersection observer threshold is appropriate for your layout. Elements that are initially visible might not trigger if threshold is too high.

Performance issues with long text: The component creates individual motion spans for each word/letter. For very long text, consider breaking content into multiple BlurText components or using animateBy="words" instead of "letters".

Custom animations not working: When providing custom animationFrom and animationTo props, ensure all keyframe objects have consistent property keys. Missing properties in intermediate keyframes can cause animation glitches.

Text spacing issues: The component preserves spacing using non-breaking spaces (\u00A0). If you encounter spacing issues, check your CSS word-spacing and letter-spacing properties that might interfere.

Blur not visible on some devices: CSS filter blur requires hardware acceleration. On older devices or certain browsers, the blur effect might be subtle or disabled for performance reasons.

Integration with other components

Perfect for hero sections in Card layouts or scroll-triggered reveals in Dialog modals. Works excellently with Badge components for feature announcements or Button components with complementary entrance animations.

For landing pages, combine with Progress indicators that animate alongside text reveals or Separator components for sectioned content reveals. The component integrates seamlessly with Tabs for content that appears as users navigate between sections.

Questions developers actually ask