For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The dithercn agent skill, for building any dither on the engine, is at /.well-known/agent-skills/dithercn/SKILL.md.
dithercn

Halftone

A print halftone: round dots on a rotated screen that swell and shrink with a source, in one ink or up to three overlapping like CMYK.

Controls
Source
Inks
Ink
Size10px
Angle45°
Intensity0.9
Drift1
Animate

Installation

pnpm dlx shadcn@latest add https://dithercn.dev/r/halftone.json

Usage

import { Halftone } from "@/components/dithercn/halftone";
 
export function Hero() {
  return (
    <section className="relative isolate min-h-[480px]">
      <Halftone color="blue" className="absolute inset-0 -z-10" />
      <h1>Your headline</h1>
    </section>
  );
}

Each square of a rotated screen holds one round dot, sized by the source at its centre, the way a printing screen works. Dot edges are dithered at the screen's own device pixels, so dots stay round and grow smoothly from a speck to touching their neighbours. The screen slides slowly along its angle (drift), so dots swell and shrink as they cross the source.

Pass channels instead of color for two or three inks. Each gets its own screen, turned 30° from the last, and overlapping dots mix their colours. With blue, pink and orange you get the rosettes of a CMYK print.

Examples

Spotlight behind a headline

source="radial" grows the dots towards center. With the centre below the bottom edge, a radius under 1 and a transparent background, the dots swell up from the bottom of the section and run out before the text.

Duotone ramp in a card

source="linear" grows the dots towards direction. Two channels at a shallow 15° screen, held still, and faded in from the left with a CSS mask.

Three-ink print

A coarse 16px screen in three inks behind an editorial block.

Props

PropTypeDefault
color

Colour of the dots: a palette name such as "blue", a CSS variable name, or any CSS colour.

Type: DitherColorDefault "ink"
channels

Two or three inks on separate screens, 30° apart. Overlaps mix. Use instead of color.

Type: [DitherColor, DitherColor, DitherColor?]Default –
background

Colour behind the dots. "transparent" lays the screen over the content underneath.

Type: DitherColorDefault "--dither-paper"
source

What sizes the dots: soft drifting clouds, distance from a point, or a ramp.

Type: "noise" | "radial" | "linear"Default "noise"
center

Radial only. Where the dots are largest, as fractions of the box from the top left.

Type: [x: number, y: number]Default [0.5, 0.5]
radius

Radial only. Where the dots run out. 1 reaches the farthest corner.

Type: numberDefault 1
direction

Linear only. Direction the dots grow towards, in degrees as in CSS.

Type: numberDefault 0
size

Distance between dot centres in CSS pixels.

Type: numberDefault 10
angle

Screen angle in degrees. Each extra channel adds 30°.

Type: numberDefault 45
intensity

Size of the largest dot, 0 to 1. At 1 the biggest dots just touch.

Type: numberDefault 0.9
scale

Noise only. Size of the clouds.

Type: numberDefault 1
drift

How fast the screen slides along its angle. 0 holds the screen still.

Type: numberDefault 1
speed

How fast the source moves.

Type: numberDefault 1
animate

false draws one still frame.

Type: booleanDefault true
cell

Size of one rendered pixel in CSS pixels. Larger cells give blockier dots.

Type: numberDefault one device pixel
className

Size and position. The halftone fills this box.

Type: stringDefault –

Notes

  • The halftone 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 a CSS dot screen in the same inks.
  • Overlap colours are mixed with CSS color-mix in oklch, so they follow the theme along with the inks.