Noise / Film Grain
`<pura-noise>` lays an animated film-grain texture over its slotted content (or over anything, when positioned as a fixed full-page layer), the analog finish seen on nearly every awwwards site. The grain is an SVG `feTurbulence` tile embedded as a data URI in the background of an overlay layer, shuffled by a `steps()` `@keyframes` on `background-position`, so the whole effect is CSS: zero per-frame JS, deterministic, and the static texture paints on SSR before any script runs. `opacity`, `size`, `frequency`, `fps` and `blend` tune the look; `static` keeps the texture without motion, and reduced motion holds the grain still automatically. The grain layer is `pointer-events: none` and exposed via `part="grain"`. Each instance registers in `window.__puraNoises` by `data-pura-id` with `{ opacity, fps, static }`.
Preview
<!-- grain over a hero image -->
<pura-noise opacity="0.12" blend="soft-light">
<img src="https://picsum.photos/seed/grain/1200/600" alt="Hero" style="display: block; width: 100%;" />
</pura-noise>
<!-- subtle static grain finish over the whole page -->
<pura-noise static opacity="0.05" size="180"
style="position: fixed; inset: 0; pointer-events: none; z-index: 9999;"></pura-noise> Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
opacity | number | 0.08 | Grain opacity, 0..1. |
size | number | 256 | Rendered tile size in px; smaller means finer grain. |
frequency | number | 0.8 | feTurbulence baseFrequency, 0.05..4; higher means denser noise. |
fps | number | 12 | Grain shuffle frames per second, 1..60. |
blend | string | overlay | mix-blend-mode of the grain layer, e.g. overlay, soft-light, normal. |
static | boolean | false | Keep the grain texture but never animate it. |
Installation
pura is copy-paste and dependency-free. Load the whole library, or just this component.
<link rel="stylesheet" href="/pura/tokens.css">
<script type="module" src="/pura/lib/noise.js"></script> import "./pura/lib/noise.js";