Twelve photo effects, recreated in CSS. The reference is Photo Effects Bundle Vol. 1 — twelve Photoshop asset packs, each a stack of smart objects, adjustment layers and displacement maps. Everything below does the same job with blend modes, filters, gradients and masks, and nothing else: no canvas, no WebGL, no image editing, no build step. Every panel is the same eight empty <span> elements; only the data-effect attribute differs.
Pick a different source photograph, or drop in your own — the whole gallery re-renders, because every effect is a process rather than a picture. Click any panel to see it large, arrow between them, and unfold the CSS that produced it.
Teardown
Each panel is a 4:3 frame containing six stacked photo layers inside a blend-isolation group, plus two overlay layers that sit above any filter applied to that group. Every layer already carries the photograph as its background image and starts hidden; an effect switches on the two or three it needs. That fixed skeleton is what makes the source swappable: the photo enters once, as a single --pe-img custom property on the gallery root.
The workhorse is a threshold trick that shows up in four of the twelve. Blend a gradient tile — lines for a scan screen, dots for a halftone — onto a grayscale photo with hard-light, then push the composite through filter: contrast(16). The blend makes the tile’s local luminance track the photograph’s, and the contrast collapses everything to pure black or pure white, so what survives is a pattern whose stroke weight follows the image. No continuous tone remains, which is exactly what a halftone screen does to ink on paper.
The rest is more direct: duotones from a lighten/darken pair of solid colours, chromatic aberration from three channel-isolated copies composited with screen, refraction from a repeating mask that displaces alternate diagonal bands, shattered glass from nine clip-path shards that each rotate a fraction of a degree.
Because a panel renders at ~390px in the grid and ~1050px in the viewer, every displacement, blur radius and pattern size is expressed in container units — 1cqw is one percent of the panel’s own width — so an effect is the same at both sizes rather than a coarser or finer one.
The listing under each panel in the viewer is not a copy of the CSS: the script fetches the shipped stylesheet and slices out the block for the effect on show, so it cannot drift from the rules the browser is actually applying.
Animation is confined to prefers-reduced-motion: no-preference — a flicker on the scan screen, drift on the tape tracking bands and the faintest motion echo. With reduced motion every panel renders complete and still. The source photograph you pick is read locally with URL.createObjectURL and never leaves the browser.