Grain Overlay
A subtle animated film-grain texture over your hero or card, mix-blend-screen so it reads as depth, not noise-on-top. The tactile-editorial look on 2025/2026 award sites, done as one SVG data URI + CSS steps() jitter — no canvas, no JS loop.
const GRAIN_SVG =
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E";
export function GrainOverlay({ children }) {
return (
<div className="relative h-full w-full overflow-hidden rounded-2xl bg-[#0a0e1a]">
<div
aria-hidden
className="grain-drift pointer-events-none absolute -inset-[200%] opacity-[0.22] mix-blend-screen"
style={{ backgroundImage: `url("${GRAIN_SVG}")` }}
/>
<div className="relative flex h-full w-full items-center justify-center">
{children}
</div>
<style>{`
.grain-drift { animation: grain-drift-shift 0.7s steps(6) infinite; }
@keyframes grain-drift-shift {
0% { transform: translate(0%, 0%); }
20% { transform: translate(-4%, 4%); }
40% { transform: translate(4%, -2%); }
60% { transform: translate(-2%, -4%); }
80% { transform: translate(3%, 3%); }
100% { transform: translate(0%, 0%); }
}
`}</style>
</div>
);
}How it works
Grain Overlay is a hand-built background component for React, styled with Tailwind and animated with Framer Motion — no heavy dependency tree, no 60-package install. Drop it in, keep your bundle lean, and it stays performant on real devices. It's free — copy the code above and ship it.
← Browse all components