Noise/Grain Texture
Cinematic grain texture in pure CSS — a ::after pseudo-element overlays an SVG feTurbulence noise on any surface, no JS, no canvas.
You'll get access to the interactive demo with a free account.
This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Backgrounds has 50 effects, including 6 free. Explore the category →
3 usage examples



How it works
The effect relies on a ::after pseudo-element positioned at inset: 0 on the container. This pseudo-element receives a background-image pointing to an SVG filter encoded as a data URI — no canvas, no server image, no JS: a single CSS rule does it all.
The URI embeds an SVG <filter> with a <feTurbulence> primitive in fractalNoise mode. The baseFrequency='0.65' parameter sets the granularity (close to 35 mm film grain density) and numOctaves='3' stacks three fractal detail levels for an organic rather than mechanical look. A <rect> covers 100% of the SVG viewport with that filter applied.
stitchTiles='stitch' asks the SVG engine to match tile edges: the noise repeats invisibly, whatever the container size. opacity: 0.15 keeps the grain subtle — it layers over the #1a1a2e background without overpowering it. pointer-events: none lets all clicks pass through the pseudo-element.
No JS is involved, no requestAnimationFrame runs — the grain is static, computed once by the rendering engine. CPU cost after the first paint is zero. The effect is compatible with any HTML content positioned above it (higher z-index).
Accessibility
- No prefers-reduced-motion handling needed: the effect is entirely static, no animation runs.
- The
::afterpseudo-element is invisible to assistive technologies by nature — screen readers do not traverse CSS pseudo-elements. pointer-events: noneis set on the grain layer: no interaction is captured, underlying clickable elements work normally.- The demo text (
.bg-label, white#fff) over the#1a1a2ebackground exceeds the WCAG AA contrast ratio (4.5:1). - The effect is purely decorative; if the container holds no text content, add
aria-hidden="true"to explicitly exclude the block from the accessibility tree.
Browser compatibility
Requires SVG feTurbulence filter support and data URI in background-image — available in all modern browsers.
If the browser does not support SVG filters in data URIs, the <code>::after</code> displays no texture — the background stays <code>#1a1a2e</code>, no JS errors, the page remains functional.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="bg-noise-new" style="width:100%;min-height:300px;">
<!-- Content layered above the texture (container must be position relative) -->
<span class="bg-label">Your text</span>
</div>
Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
| baseFrequency (SVG) | 0.65 | Noise granularity: 0.3 = coarse grain (large film stock), 0.65 = 35 mm, 0.9 = very fine grain / dust. Edit the value inside the encoded SVG URI. |
| numOctaves (SVG) | 3 | Fractal detail levels. 1 = flat, uniform texture; 4–5 = very organic. Useful values: 2 (light), 3 (default), 4 (rich). |
| .bg-noise-new::after { opacity } | 0.15 | Visible grain intensity. 0.08 = subtle hint, 0.20 = visible grain, 0.35 = strong film texture. |
| .bg-noise-new { background } | #1a1a2e | Surface color beneath the grain. Change it without touching the pseudo-element — the grain overlays any background color or gradient. |
| type (SVG feTurbulence) | fractalNoise | SVG noise mode. fractalNoise = soft analog grain. turbulence = cloudier, high-contrast pattern — works for horror or brutalist aesthetics. |
| viewBox SVG (200 200) | 200 200 | Base tile size before repeating. Shrink to 100 100 to double the apparent grain size; increase to 400 400 to refine it further. |
FAQ
feTurbulence primitive generates deterministic noise computed once by the SVG rendering engine — no requestAnimationFrame, no JS running. The grain does not change between frames, which gives it an analog-photo feel rather than a TV-noise look..bg-noise-new { background } to any color or linear-gradient. For a light background, lower opacity to 0.06–0.10 and consider adding mix-blend-mode: multiply to the ::after for a more natural result on white surfaces.stitchTiles='stitch' in the SVG primitive. The engine computes the noise so that tile edges connect seamlessly — the repetition is imperceptible even across a full-screen banner.