SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/grain-textures

7 CSS Grain and Noise Textures

7 Pure CSSPublished 2026-10-05Free · no sign-up

Seven texture effects made without image files: film grain from an SVG noise filter, a warm paper texture, a gradient with grain to hide banding, a matte textured button, comic halftone dots, grain over a photo and grain that flickers like projected film.

01. SVG Noise Overlay

GrainTexture

Film grain from an inline SVG feTurbulence filter used as a background image on a pseudo-element, blended over a gradient. The noise is generated by the browser, so it costs no image download and scales to any size.

View code
<section class="gr1"><h3>Analog hours</h3><p>Records, coffee and long afternoons.</p></section>
.gr1 { position: relative; isolation: isolate; width: 300px; max-width: 100%; padding: 30px 20px; box-sizing: border-box; border-radius: 18px; background: linear-gradient(135deg, #7c2d12, #be123c 60%, #4c1d95); color: #fff7ed; font: 14px Inter, system-ui, sans-serif; overflow: hidden; }
.gr1::after { content: ""; position: absolute; inset: 0; z-index: -1; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); opacity: .28; mix-blend-mode: overlay; }
.gr1 h3 { margin: 0 0 4px; font-size: 26px; } .gr1 p { margin: 0; color: #fed7aa; }

02. Paper Texture Card

GrainPaper

A note card on a warm paper texture, made from fine noise multiplied over a cream colour. Lower turbulence frequencies give coarser grain; this one is fine enough to feel like paper without distracting from the text.

View code
<article class="gr2"><h3>Dear reader,</h3><p>Thank you for ordering from our little studio. Every piece was packed by hand.</p></article>
.gr2 { position: relative; isolation: isolate; width: 280px; max-width: 100%; padding: 22px; box-sizing: border-box; border-radius: 6px; background: #faf6ec; color: #3f2d1d; font: 15px/1.6 Georgia, serif; box-shadow: 0 8px 18px -10px rgba(63,45,29,.5); }
.gr2::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.65' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 .4 0 0 0 0 .3 0 0 0 0 .2 0 0 0 .35 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)'/%3E%3C/svg%3E"); mix-blend-mode: multiply; }
.gr2 h3 { margin: 0 0 6px; font-style: italic; } .gr2 p { margin: 0; }

03. Grainy Gradient Background

GrainGradient

Smooth gradients can show visible banding on some screens. A light layer of grain breaks up the bands and gives the colour a printed, tactile quality, a popular look for modern landing pages.

View code
<section class="gr3"><p>No banding, just grain.</p></section>
.gr3 { position: relative; display: grid; place-items: center; width: 300px; max-width: 100%; height: 200px; border-radius: 18px; background: radial-gradient(circle at 20% 20%, #f472b6, transparent 50%), radial-gradient(circle at 80% 80%, #38bdf8, transparent 55%), #312e81; font: 700 16px Inter, system-ui, sans-serif; color: #fff; overflow: hidden; }
.gr3::after { content: ""; position: absolute; inset: 0; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: .22; mix-blend-mode: soft-light; pointer-events: none; }
.gr3 p { position: relative; margin: 0; padding: 6px 12px; border-radius: 8px; background: rgba(15,23,42,.45); }

04. Grain-Textured Button

GrainButton

A button with a subtle grain on its fill, which makes a flat colour feel like riso print or matte plastic. The grain is a background layer over the colour, so the text stays crisp on top.

View code
<button class="gr4">Order prints</button>
.gr4 { padding: 14px 26px; border: 0; border-radius: 12px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .2 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23b)'/%3E%3C/svg%3E"), #0f766e; color: #fff; font: 800 15px Inter, system-ui, sans-serif; cursor: pointer; }
.gr4:hover { background-color: #115e59; }
.gr4:focus-visible { outline: 3px solid #5eead4; outline-offset: 3px; }

05. Halftone Dot Texture

GrainHalftone

A comic-book halftone made from a radial-gradient dot pattern, masked so the dots fade out across the panel. Unlike noise, halftone is regular, which gives a graphic, printed feel rather than a photographic one.

View code
<section class="gr5"><h3>POW!</h3></section>
.gr5 { position: relative; display: grid; place-items: center; width: 280px; max-width: 100%; height: 190px; box-sizing: border-box; border: 3px solid #111; background: #fde047; overflow: hidden; }
.gr5::before { content: ""; position: absolute; inset: 0; background: radial-gradient(circle, #f97316 2.5px, transparent 3px) 0 0 / 10px 10px; -webkit-mask: linear-gradient(120deg, #000 10%, transparent 75%); mask: linear-gradient(120deg, #000 10%, transparent 75%); }
.gr5 h3 { position: relative; margin: 0; color: #111; font: 900 56px Impact, "Arial Black", sans-serif; transform: rotate(-6deg); text-shadow: 4px 4px 0 #fff; }

06. Grain over an Image Card

GrainImage

A card where grain sits over the picture but under the caption, giving the image a film-photo quality while keeping the text sharp. The stacking is three layers: image, grain pseudo-element and caption.

View code
<figure class="gr6"><div class="im" role="img" aria-label="Sunset over a harbour"></div><figcaption>Harbour, 35 mm</figcaption></figure>
.gr6 { position: relative; width: 260px; max-width: 100%; margin: 0; border-radius: 14px; overflow: hidden; font: 600 13px Inter, system-ui, sans-serif; }
.gr6 .im { aspect-ratio: 4 / 3; background: linear-gradient(#fdba74, #f472b6 45%, #1e3a8a 46%, #0f172a); }
.gr6::after { content: ""; position: absolute; inset: 0; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E"); opacity: .3; mix-blend-mode: overlay; pointer-events: none; }
.gr6 figcaption { position: absolute; left: 10px; bottom: 10px; z-index: 1; padding: 4px 8px; border-radius: 6px; background: rgba(0,0,0,.6); color: #fff; }

07. Flickering Film Grain

GrainAnimation

Grain that jumps position in quick steps, like the flicker of projected film. The noise layer is larger than the panel and moves between offsets with steps(), and it stays still for anyone who prefers reduced motion.

View code
<section class="gr7"><h3>The Long Night</h3><p>A short film · 2026</p></section>
.gr7 { position: relative; isolation: isolate; width: 300px; max-width: 100%; padding: 36px 20px; box-sizing: border-box; border-radius: 16px; background: #1c1917; color: #f5f5f4; font: 14px Georgia, serif; text-align: center; overflow: hidden; }
.gr7::after { content: ""; position: absolute; inset: -50%; z-index: -1; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23m)'/%3E%3C/svg%3E"); opacity: .18; animation: gr7 .6s steps(3) infinite; }
.gr7 h3 { margin: 0 0 6px; font-size: 26px; letter-spacing: .08em; } .gr7 p { margin: 0; color: #d6d3d1; }
@keyframes gr7 { 0% { transform: translate(0, 0); } 33% { transform: translate(-12%, 8%); } 66% { transform: translate(9%, -10%); } }
@media (prefers-reduced-motion: reduce) { .gr7::after { animation: none; } }

About these CSS Grain and Noise Textures

Noise from SVG

An inline SVG with feTurbulence generates noise in the browser. Used as a data URL background, it needs no download and tiles at any size.

Blend it in

Lay the noise over colour with mix-blend-mode (overlay, soft-light or multiply) and a low opacity. A little grain goes a long way.

Grain fixes banding

Large smooth gradients can show visible steps on some screens. A faint grain layer breaks them up and makes the colour feel richer.

Keep text off the noise

Put grain behind or under text layers, not over them, so letters stay crisp and readable.

Frequently asked questions

Does SVG noise hurt performance?

Static noise is cheap. Animated noise over large areas costs more, so keep it small or pause it.

Can I change the grain size?

Lower baseFrequency gives coarser grain; higher gives finer.

Does the flicker respect reduced motion?

Yes, it stops under prefers-reduced-motion.