Installation
pnpm dlx shadcn@latest add https://dithercn.dev/r/contours.jsonUsage
import { Contours } from "@/components/dithercn/contours";
export function Section() {
return (
<section className="relative isolate min-h-[480px]">
<Contours className="absolute inset-0 -z-10" />
<h2>Your heading</h2>
</section>
);
}Contour lines trace even steps of height across a field of low hills. Every fifth line is drawn heavier, as on a survey map, and slopes facing away from a light in the top left pick up a light stipple. The hills drift and slowly change shape. They keep their size in pixels, so a narrow box shows a smaller piece of the same map rather than a squashed one.
Examples
Survey map
More lines, a smaller scale and a little more relief in green and brown give an old ordnance survey sheet. cell={2} keeps the lines fine.
Behind a headline
Set index and relief to 0 for plain lines, and pass two soft tints of the ink so the lines never reach full contrast.
Props
| Prop | Type | Default |
|---|---|---|
| lines How many contour lines from the lowest ground to the highest, from 4 to 32. | Type: number | Default 14 |
| scale Size of the hills. Higher values pack more of them in. | Type: number | Default 1 |
| index Every how many lines one is drawn heavier. 0 draws them all the same. | Type: number | Default 5 |
| relief How strongly slopes facing away from the light are shaded, from 0 to 1. | Type: number | Default 0.5 |
| palette Colours from paper to ink: palette names such as "blue", CSS variable names, or any CSS colour. | Type: [DitherColor, DitherColor, ...DitherColor[]] | Default Paper, a tint of --dither-ink, then --dither-ink |
| matrix The threshold pattern. See Dither engine. | Type: "bayer2" | "bayer4" | "bayer8" | "blue-noise" | Default "bayer4" |
| cell Size of one dither cell in CSS pixels. | Type: number | Default --dither-cell |
| speed How fast the hills drift. | Type: number | Default 1 |
| animate false draws one still frame. | Type: boolean | Default true |
| className Size and position. The map fills this box. | Type: string | Default – |
Notes
- It is decorative and hidden from assistive technology. Put real text on top of it, not inside it.
- With reduced motion turned on, it draws one still frame and stops.
- It pauses when scrolled out of view or when the tab is hidden, and releases its WebGL context when far offscreen. Without WebGL it shows faint CSS rings.