The Problem with Perfect
Modern screens are too precise. Every pixel lands exactly where it's told. Colors are uniform, edges are sharp, and everything looks like it was manufactured by a machine — because it was.
This perfection is, paradoxically, what makes digital design feel cold. Our eyes evolved in a world of texture: rough stone, woven cloth, imperfect paper. Perfectly smooth surfaces are rare in nature, and the brain registers them as artificial.
What Film Grain Does
Film grain is the visible texture of silver halide crystals suspended in photographic emulsion. In analog photography, it's a byproduct — random noise introduced by the medium itself.
But in digital design, it's a choice. And it's a powerful one.
When you add a subtle grain overlay to a digital interface, you're doing several things at once:
- Softening the harshness of solid colors and hard-edged shadows
- Adding depth — grain reads as a surface, not a flat plane
- Evoking nostalgia — we associate grain with film, with warmth, with humanity
- Reducing the "screenshot" quality that makes digital work look flat
How to Implement It
The simplest approach is an SVG noise filter applied as a fixed overlay:
<svg>
<filter id="grain">
<feTurbulence
type="fractalNoise"
baseFrequency="0.65"
numOctaves="3"
stitchTiles="stitch"
/>
<feColorMatrix type="saturate" values="0"/>
</filter>
<rect width="100%" height="100%" filter="url(#grain)"/>
</svg>
Set it to position: fixed, pointer-events: none, z-index: 50, and a low opacity (I use 0.03–0.05). It sits invisibly on top of everything, adding texture without obscuring content.
Getting the Amount Right
Too much grain and you look like you're designing a horror movie poster. Too little and you can't tell it's there at all.
I target an opacity where you can only feel the grain rather than see it. When you toggle it off, the page suddenly looks flat and sterile. That's the sweet spot.
A Note on Performance
SVG filters are GPU-accelerated in modern browsers, so the performance cost is negligible. The main concern is that the turbulence pattern is regenerated on resize — worth noting but rarely a problem in practice.
Closing
Grain is a small thing. It's a 2kb SVG and three lines of CSS. But it's the difference between a design that feels like software and a design that feels like it was made by a human who cares.
That's worth the complexity.