Componentregistry:component
Grain & Paper Overlay
A lightweight, pointer-transparent film grain, paper or fibre texture you can drop on any section or fix over the whole page. SVG noise, optional tint and flicker, server-component safe.
Installation
$ npx shadcn@latest add @creative-ui/grain-overlayOn an older shadcn CLI, use the URL: npx shadcn@latest add https://ui.krutikraut.com/r/grain-overlay.json
Preview
Section · 04
Printed on paper, not pixels.
The overlay sits above this content, ignores the pointer and reads on light and dark alike.
Get startedRead the notes
Variant
Surface
Opacity0.25
Usage
Example.tsx
import { GrainOverlay } from "@/components/grain-overlay"
export function Section() {
return (
<section className="relative bg-[#f4efe6] p-16">
<h2>Made by hand</h2>
<GrainOverlay variant="paper" />
</section>
)
}
// Or once, over the whole page:
<GrainOverlay fixed animate opacity={0.12} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "grain" | "paper" | "fiber" | "grain" | grain is fine film grain. paper is warm stock with fine tooth and faint mottling. fiber is handmade paper with loose strands. Sets the defaults for the props below. |
| opacity | number | per variant | Layer opacity, 0 to 1. Grain 0.25, paper 0.45, fiber 0.5. |
| frequency | number | [number, number] | per variant | Frequency of the variant's main noise. Higher is finer. A pair sets x and y separately. Grain 0.85, paper tooth 0.9, fiber strands 0.03. |
| octaves | number | per variant | Octaves of the main noise. More add finer detail. Grain 4, paper 3, fiber 1. |
| contrast | number | per variant | How hard the specks are cut from the noise. Higher is crisper and stronger. Grain 2.2, paper 1.8, fiber 28. |
| seed | number | 2 | Noise seed, so two overlays can differ or match. |
| size | number | per variant | Tile size in px. Grain 240, paper and fiber 480. |
| color | string | — | Paint every speck in one colour. Any CSS colour works, including var(--primary) and currentColor. When omitted, the texture uses dark and light specks. |
| blend | CSSProperties["mixBlendMode"] | "normal" | CSS mix-blend-mode. The texture is already dark and light specks on transparency, so it needs no blend mode. Set one for a specific look, such as soft-light over photos. |
| fixed | boolean | false | Cover the viewport instead of the nearest positioned ancestor. |
| animate | boolean | false | Film flicker: the grain jumps between eight held frames at about 10fps. It runs on the compositor and stays still for users who prefer reduced motion. |
Also accepts every div prop, which is spread onto the root element.
Also exported
- noiseTexture({ variant?, frequency?, octaves?, contrast?, seed?, size? })
- Builds a variant's tiling SVG noise as a CSS
url(). The alpha channel carries the texture, so it works as abackground-imageor amask-image. - grainPresets
- The default size, opacity, colours and noise layers for each variant.
Notes
- Place it inside an element with
position: relative. It fills that element and never blocks clicks. - It reads on light, dark and photographic surfaces without a blend mode, because each pixel is either transparent or a dark or light speck.
fixedusesz-50. Override it withclassNameif it covers dialogs or toasts.- It is hidden when printing and in forced-colours mode.
- No client JavaScript, so it is safe in React Server Components. With
animate, the keyframes are added to the page once, however many overlays use them.
Dependencies
shadcn/utils
