Works natively with Cursor. Add npx -y bare-ui-mcp to your MCP settings.

Blur Fade

A smooth reveal animation that blurs and fades in elements as they scroll into view.

Scroll down to reveal

This component smoothly fades and blurs in its children as they enter the viewport.

Zero Dependencies

No Framer Motion or React Spring needed.

Pure Native CSS

Smooth animations using hardware acceleration.

Intersection Observer

Only animates when visible in viewport.

Highly Customizable

Adjust blur, delay, offset, and duration.

Installation

1. Copy the React component into your project:

tsx
"use client";

import React, { useRef, useState, useEffect } from "react";

export interface BlurFadeProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
  delay?: number;
  duration?: number;
  blur?: string;
  yOffset?: number;
}

export const BlurFade = ({
  children,
  className = "",
  delay = 0,
  duration = 0.8,
  blur = "10px",
  yOffset = 20,
  ...props
}: BlurFadeProps) => {
  const ref = useRef<HTMLDivElement>(null);
  const [isVisible, setIsVisible] = useState(false);

  useEffect(() => {
    const currentRef = ref.current;
    if (!currentRef) return;

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry && entry.isIntersecting) {
          setIsVisible(true);
          observer.unobserve(currentRef);
        }
      },
      {
        threshold: 0.1,
      }
    );

    observer.observe(currentRef);

    return () => {
      if (currentRef) {
        observer.unobserve(currentRef);
      }
    };
  }, []);

  return (
    <div
      ref={ref}
      className={`bare-blur-fade ${isVisible ? "visible" : ""} ${className}`}
      style={
        {
          "--blur-fade-delay": `${delay}s`,
          "--blur-fade-duration": `${duration}s`,
          "--blur-fade-blur": blur,
          "--blur-fade-y": `${yOffset}px`,
        } as React.CSSProperties
      }
      {...props}
    >
      {children}
    </div>
  );
};

2. Add the native CSS to your global stylesheet:

css
/* Bare Blur Fade Animation */
.bare-blur-fade {
  opacity: 0;
  transform: translateY(var(--blur-fade-y, 20px));
  filter: blur(var(--blur-fade-blur, 10px));
  transition: opacity var(--blur-fade-duration, 0.8s) ease-out,
              transform var(--blur-fade-duration, 0.8s) ease-out,
              filter var(--blur-fade-duration, 0.8s) ease-out;
  transition-delay: var(--blur-fade-delay, 0s);
  will-change: opacity, transform, filter;
}

.bare-blur-fade.visible {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

Usage

tsx
import { BlurFade } from '@/components/ui/blur-fade';

export default function MyComponent() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
      <BlurFade delay={0.1}>
        <h2>First Item</h2>
      </BlurFade>

      <BlurFade delay={0.3} blur="20px" yOffset={40}>
        <p>Second Item with custom blur and offset</p>
      </BlurFade>

      <BlurFade delay={0.5} duration={1.2}>
        <p>Third Item with slower animation</p>
      </BlurFade>
    </div>
  );
}