effectsbeginner

Grain Texture

A CSS or SVG noise overlay applied to backgrounds to add tactile depth and prevent gradients from looking flat — generated via SVG feTurbulence or a Base64 noise data URI.

Plain English

Smooth gradients look digital and synthetic. A thin layer of noise or grain — the same visual texture you see in film photography or premium print — makes a gradient feel physical and warm. Grain texture is the secret ingredient behind many "how did they make this look so good?" hero sections: the gradient itself might be unremarkable, but the fine noise overlay sitting above it at 6–10% opacity is what gives it depth and prevents the color from looking like a screensaver. The technique is borrowed from print design, where paper stock adds natural variation that digital screens lack. In UI, grain also serves a subtle function beyond aesthetics: it reduces Mach banding (the visible banding artifact that appears in gradients on some displays), making large gradient backgrounds look smoother on lower-quality monitors. Implementation requires either an SVG filter with feTurbulence applied to a full-screen pseudo-element, or a pre-generated noise image as a data URI tiled across the background.

Technical

SVG filter method (recommended, no asset needed): embed <svg> with <filter id="grain"><feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch" /></filter> then on a pseudo-element: content: ""; position: absolute; inset: 0; background: url(#grain); opacity: 0.07; pointer-events: none; mix-blend-mode: overlay. Data URI method: use a PNG/WebP noise texture as background-image on an ::after pseudo-element with background-repeat: repeat; background-size: 200px 200px; opacity: 0.08. Animated grain: @keyframes grain-shift with transform: translate(random%) on the pseudo-element at 0%, 10%, 20%... 100% to make the grain appear to shimmer — used sparingly, 0.15s steps. Key properties: pointer-events: none (never intercept clicks), position: absolute with a positioned parent, and z-index layering above the background but below the content.

Live Demo

Grain Texture

A noise overlay softens digital-feeling gradients, giving them a tactile, printed quality.

Plain gradient

Digital & flat

No texture — feels sterile

Gradient + grain

Tactile & rich

Grain at 35% opacity

35%
SubtleHeavy

/* SVG feTurbulence noise overlay */
mix-blend-mode: overlay;
opacity: 0.35;
background: url('noise.svg') repeat;

Mix-blend-mode: overlay ensures the grain adapts to both light and dark areas of the gradient.

Usage

✓ Good usage

An aurora hero section with a grain-texture pseudo-element at 7% opacity and mix-blend-mode: overlay — the gradient transitions between colors smoothly and the surface feels tactile rather than digitally rendered.

✗ Bad usage

A data table with grain texture at 15% opacity applied to the entire page — the noise interferes with text legibility and makes numbers in the table harder to read quickly.

Common mistakes

AI Prompt Example

Copy this into Claude, Cursor, Bolt, or v0.

Add a grain texture overlay to the hero section background. Create an ::after pseudo-element on the hero wrapper: position: absolute; inset: 0; pointer-events: none; opacity: 0.07; mix-blend-mode: overlay; background-image: url("data:image/svg+xml,...") (SVG with feTurbulence baseFrequency="0.65" numOctaves="3"). Ensure the hero wrapper has position: relative and the grain sits above the gradient layer but below all text and CTA elements using z-index. Test at different opacity values between 5% and 10% — choose whichever makes the gradient feel most tactile without looking dirty.