Back to Dictionary
Waiting & Loading
●○○Ready to Use
Recommended defaultImage Lazy Load Fade
Images load as low-res blurs or empty blocks and gently crossfade into their full high-resolution versions instead of popping in jarringly line-by-line.
Use
Image-heavy galleries
Avoid
Critical text content or SVGs that load instantly
Safer Alternative
No safer default listed.
Risk Level
Low risk
Live Demo
Loading...
What It Is
Images load as low-res blurs or empty blocks and gently crossfade into their full high-resolution versions instead of popping in jarringly line-by-line.
✓When to Use
- Image-heavy galleries
- E-commerce product grids
✕When NOT to Use
- Critical text content or SVGs that load instantly
Configuration Tips
- 01Keep the fallback background a soft gray or extract the dominant color of the image
You've Seen It In
MediumPinterestUnsplash
AI Implementation Prompts
Move from a fast scaffold to production details, then tune timing and edge states.
Add a lazy loading fade effect to all images on this grid.
Reference Implementation
The same implementation approach used by the live preview, kept compact enough to inspect and adapt.
"use client";
import { motion, AnimatePresence } from 'framer-motion';
import { useState, useEffect } from 'react';
export function ImageLazyLoadFadeDemo({ isPlaying = false }: { isPlaying?: boolean }) {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
if (!isPlaying) {
setIsLoaded(false);
return;
}
setIsLoaded(false);
const timer = setTimeout(() => setIsLoaded(true), 1200);
"text-stone-400 italic">// Loop it every 3.5 seconds
const loop = setInterval(() => {
setIsLoaded(false);
setTimeout(() => setIsLoaded(true), 1200);
}, 3500);
return () => {
clearTimeout(timer);
clearInterval(loop);
};
}, [isPlaying]);
return (
<div className="flex h-64 w-full items-center justify-center overflow-hidden rounded-2xl bg-white p-4 shadow-sm ring-1 ring-stone-200">
<div className="relative w-48 h-48 rounded-xl overflow-hidden bg-stone-100 flex items-center justify-center shadow-inner">
{"text-stone-400 italic">/* Low res blur / skeleton placeholder */}
<AnimatePresence>
{!isLoaded && (
<motion.div
className="absolute inset-0 bg-stone-200/50 backdrop-blur-md z-10 flex items-center justify-center"
initial={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.6 }}
>
<span className="text-stone-400 text-xs tracking-widest uppercase font-medium">Loading...</span>
</motion.div>
)}
</AnimatePresence>
{"text-stone-400 italic">/* High res image */}
<motion.img
src="https:">//images.unsplash.com/photo-1618005182384-a83a8bd57fbe?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80"
alt="Abstract art"
className="object-cover w-full h-full"
initial={{ filter: "blur(10px)", scale: 1.05 }}
animate={{
filter: isLoaded ? "blur(0px)" : "blur(10px)",
scale: isLoaded ? 1 : 1.05
}}
transition={{ duration: 0.8, ease: "easeOut" }}
/>
</div>
</div>
);
}