Snippets / Color & Theming /

Noise Texture

Add grain texture to any element using an inline SVG feTurbulence filter applied via CSS — no images, no JavaScript.

Flat
No texture
Grainy
With noise overlay
Widely Supported
colorno-js

Quick implementation

<!-- 1. Define the filter once in the page (hidden) -->
<svg style="position:absolute;width:0;height:0;overflow:hidden" aria-hidden="true">
  <defs>
    <filter id="noise-filter" color-interpolation-filters="sRGB">
      <feTurbulence type="fractalNoise" baseFrequency="0.7"
                   numOctaves="3" stitchTiles="stitch" result="n"/>
      <feColorMatrix type="saturate" values="0" in="n" result="grey"/>
      <feBlend in="SourceGraphic" in2="grey" mode="overlay"/>
    </filter>
  </defs>
</svg>

/* 2. Apply to any element via CSS */
.card {
  filter: url(#noise-filter);
}

/* Preserve border-radius on the filtered element */
.card {
  overflow: hidden;
  isolation: isolate;
}

/* Adjust grain size via baseFrequency (0.4 = coarse, 0.9 = fine).
   Change feBlend mode to soft-light for a subtler effect.
   Works on any background color — no image files needed. */

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a CSS expert. Add a subtle noise/grain texture to a card component using an inline SVG filter — no external image files.

Requirements:
1. Define a hidden inline <svg> with a <filter> containing: feTurbulence (type="fractalNoise", baseFrequency="0.7", numOctaves="3", stitchTiles="stitch"), feColorMatrix (type="saturate", values="0") to desaturate to grayscale, and feBlend (in="SourceGraphic", mode="overlay") to composite the noise with the element's appearance.
2. Apply the filter to any element via CSS: filter: url(#noise-filter).
3. Add overflow: hidden and isolation: isolate to the filtered element to preserve border-radius clipping.
4. Use oklch() for all color values.

Variants:
A) Subtle grain — change feBlend mode to "soft-light" for a gentler effect.
B) Strong grain — use mode="overlay" for more dramatic texture (default).
C) Fine vs coarse — adjust baseFrequency: 0.4 = coarse film grain, 0.9 = fine digital noise.

Edge cases:
- Do NOT use SVG data URIs as background-image with internal filter references — browsers sandbox data URIs and block filter="url(#id)" resolution. Always define the filter inline in the HTML document.
- CSS filter renders outside border-radius — overflow: hidden + isolation: isolate fixes this.
- The filter applies to the entire element including text — this is usually desirable for a textured look, but use a lower baseFrequency if text legibility suffers.

Why this matters in 2026

Flat design has matured to the point where subtle texture is used to restore tactile richness without heavy skeuomorphism. An SVG noise filter baked into a data URI adds zero HTTP requests and less than 300 bytes to your CSS. The feTurbulence filter generates pseudo-random grain entirely in the browser's rendering engine, making it resolution-independent and perfectly crisp on any display density.

The logic

The SVG feTurbulence filter with type="fractalNoise" generates a full-frame noise image; baseFrequency controls grain size (higher = finer) and numOctaves adds detail layers. A feColorMatrix with type="saturate" values="0" desaturates the noise to grayscale, and feBlend mode="overlay" composites it with SourceGraphic — bright noise brightens, dark noise darkens, creating organic variation without destroying the hue. The filter is defined once in a hidden inline <svg> and applied to any element via filter: url(#noise-filter).

Implementation note: SVG filter references inside data URIs (e.g. background-image: url("data:image/svg+xml,...")) do not work — browsers sandbox data URI SVGs and block internal filter="url(#id)" references. The reliable approach is to define the <filter> inline in the HTML document and reference it from CSS. Also note that CSS filter renders outside border-radius clipping — add overflow: hidden and isolation: isolate to the filtered element to restore rounded corners.

Accessibility & performance

The noise layer is purely decorative and should always have pointer-events: none and aria-hidden (implicitly satisfied by being a pseudo-element). Users with vestibular sensitivities are unaffected since the texture is static — no motion, no flicker. SVG filters are GPU-accelerated in all modern browsers, and the data URI avoids any network round-trip, making this one of the cheapest visual enhancements available.