Noise — .mv-noise
Pure-CSS film grain (SVG feTurbulence texture as a data URI) on any surface: fine or coarse, static or animated, beneath or above the content.
| Category | Effects |
|---|---|
| Type | CSS only (.mv-noise) |
| Status | stable |
| Keywords | noise, grain, texture, film, overlay, gradient |
When to use
- A flat gradient hero or card looks too digital and needs a subtle film-grain texture
- Banding must be hidden on large, smooth gradient areas
- A retro or editorial look needs coarse or flickering grain laid over the whole content
Avoid when
- High-opacity grain would sit over small or long body text and hurt legibility
Install
node scripts/add.mjs noise --out ./src/marvelousAI agent with the Marvelous UI MCP server: install_components({ slugs: ["noise"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Files copied (dependencies included): tokens/tokens.css, core/base.css, components/noise/noise.css.
Usage
Canonical markup — start from it and customize with attributes, data-* and CSS variables:
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,15rem),1fr));gap:1.25rem;width:100%;max-width:60rem;margin:auto">
<div style="display:grid;gap:.5rem">
<div style="display:grid;align-content:end;min-height:13rem;padding:1.25rem;border-radius:var(--mv-radius-xl);color:white;background:linear-gradient(150deg,oklch(0.6 0.2 285),oklch(0.55 0.22 330) 55%,oklch(0.78 0.15 60))">
<strong style="font-size:var(--mv-text-lg)">No grain</strong>
<span style="font-size:var(--mv-text-sm);opacity:.85">Smooth gradient, visible banding.</span>
</div>
</div>
<div class="mv-noise" style="display:grid;align-content:end;min-height:13rem;padding:1.25rem;border-radius:var(--mv-radius-xl);color:white;background:linear-gradient(150deg,oklch(0.6 0.2 285),oklch(0.55 0.22 330) 55%,oklch(0.78 0.15 60))">
<strong style="font-size:var(--mv-text-lg)">Fine grain</strong>
<span style="font-size:var(--mv-text-sm);opacity:.85">.mv-noise — texture beneath the content.</span>
</div>
<div class="mv-noise" data-grain="coarse" data-animate style="display:grid;align-content:end;min-height:13rem;padding:1.25rem;border-radius:var(--mv-radius-xl);color:white;background:radial-gradient(80% 70% at 20% 10%,oklch(0.7 0.16 200),transparent 70%),linear-gradient(200deg,oklch(0.35 0.12 265),oklch(0.2 0.06 280));--mv-noise-opacity:.3">
<strong style="font-size:var(--mv-text-lg)">Animated grain</strong>
<span style="font-size:var(--mv-text-sm);opacity:.85">data-grain="coarse" data-animate</span>
</div>
<article class="mv-card mv-noise" style="grid-column:1/-1;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1rem;padding:1.5rem;background:radial-gradient(120% 140% at 100% 0%,var(--mv-accent-subtle),transparent 60%),var(--mv-surface);--mv-noise-opacity:.35;--mv-noise-blend:soft-light">
<div>
<h3 style="margin:0;font-size:var(--mv-text-xl);letter-spacing:-.01em">The product team magazine</h3>
<p style="margin:.35rem 0 0;font-size:var(--mv-text-sm);color:var(--mv-fg-muted)">One issue a month, zero spam. Join 12,000 readers.</p>
</div>
<button class="mv-button" data-size="lg">Subscribe</button>
</article>
</div>API
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
data-grain | coarse | (fine) | Larger, higher-contrast grain. |
data-animate | boolean | Flickering grain (~12 fps, frozen under reduced motion). | |
data-layer | over | Grain above all the content (overlay texture). |
CSS classes
| Name | Description |
|---|---|
mv-noise | Add it to the surface (gradient, hero, card); the grain is painted in ::after between the background and the content. Makes the element positioned and isolated. |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-noise-opacity | 0.22 | Intensity. |
--mv-noise-blend | overlay | Blend mode (soft-light is subtler, multiply on light backgrounds…). |
--mv-noise-size | 200px | Tile size. |
--mv-noise-speed | 0.9s | Duration of one animated cycle. |
--mv-noise-z | 10 | z-index with data-layer="over". |
Accessibility
Decorative (pseudo-element, pointer-events: none). Keep the opacity low behind text. The animation stops under reduced motion.