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>
);
}