Paper & grain · Noise
Film grain CSS texture
Film grain is paper grain with the tile enlarged and the frequency lowered, so the flecks are bigger and read as the silver halide of a photograph rather than the fibre of a sheet. Where paper grain hides, film grain shows: it is a texture you are meant to notice, which is why it lives on dark surfaces and behind imagery rather than under body text.
Use it over a dark hero, a photo, or a gradient that looks too smooth to be real — the classic grainy-gradient effect is exactly this layer at fifteen to twenty percent. It suits editorial, music, and film. Do not use it on a productivity interface, where it reads as a broken display, and drop it entirely under prefers-reduced-motion if it animates.
Under text
Reading-size copy on the texture, so the alpha is judged by legibility rather than by taste.
A card on top
Separated without a second border.
Recipe
- Kind
- Noise
- Ink
- theme foreground at 18%
- Frequency
- 0.35
- Octaves
- 3
- Tile
- 240px
- Ink color
- color-mix(in oklab, var(--foreground) 18%, transparent)
CSS
.film-grain {
position: relative;
isolation: isolate;
}
.film-grain::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
opacity: 0.18;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.35' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
background-size: 240px 240px;
}Tailwind
relative isolate before:absolute before:inset-0 before:-z-10 before:content-[''] before:opacity-[0.18] before:bg-[image:url("data:image/svg+xml,%3Csvg_xmlns='http://www.w3.org/2000/svg'_width='240'_height='240'%3E%3Cfilter_id='n'_x='0'_y='0'_width='100%25'_height='100%25'%3E%3CfeTurbulence_type='fractalNoise'_baseFrequency='0.35'_numOctaves='3'_stitchTiles='stitch'/%3E%3CfeColorMatrix_type='saturate'_values='0'/%3E%3C/filter%3E%3Crect_width='240'_height='240'_filter='url(%23n)'/%3E%3C/svg%3E")] before:bg-[size:240px_240px]Token
--texture-film-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.35' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
--texture-film-grain-size: 240px 240px;Film grain, answered
- How is the film grain texture made in CSS?
- Film grain is an inline SVG turbulence tile, applied on a pseudo-element with an opacity — no image request, a seamless repeat, and crisp at every pixel density. Its ink is the theme's foreground color mixed to 18% with color-mix, so the same declaration re-tints itself when the theme switches between light and dark mode. The full declaration is url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.35' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E") — copy the CSS rule, the Tailwind classes or the custom property above, or open it in the playground to change the pitch, the ink or the alpha.
- How do I use the film grain texture in Tailwind CSS?
- Copy the Tailwind tab: noise needs a pseudo-element, so the output is a before: stack — relative and isolate on the element, then before:absolute, before:inset-0, before:-z-10, an opacity and the tile as before:bg-[image:…]. Tailwind v3 and v4 both accept the arbitrary values; for a value you reuse, register the Token tab's custom property instead.
- How subtle should the film grain texture be?
- Grain reads as paper fibre below about twelve percent and as dirt above it; this preset sits at 18%. Treat ten percent as the ceiling for any surface that carries body text, and lower it further behind small type.