The Surface
May 23, 2026
A single primitive replaces a catalog of one-off integrations.
The <bg-wc> custom element ships a small kernel with each visual preset
loaded only on first use. Pages that don't ask for animation pay nothing; pages that do
get a familiar attribute surface and one canvas, no matter how many presets are in play.
Fig. 1. — preset="dither" rendered in two inks: page cream and process black.
"Twenty years of animation engines, replaced by one canvas and a handful of CSS variables."
Animation arrived on the web in waves — first as GIF, then Flash, then CSS keyframes, then libraries the size of small games. Each wave promised more motion at lower friction, and each one shipped its own runtime alongside the page. The result, two decades on, is a stack of competing engines and a load budget that has nowhere left to go.
The component described in this issue takes the opposite stance. It ships a small kernel — the custom element, a renderer wrapper, a token resolver, an idle-aware request-animation-frame loop — and treats each visual preset as an isolated module loaded on first use. A page that does not use motion pays nothing.
What that looks like in practice is the figure printed at left: a halftone in two ink colors, animated by a slowly-shifting threshold. The page reads two custom properties; the component fills in the rest. No build pipeline, no framework, no images.
Whether the form catches on will depend less on the kernel and more on how readily the preset catalog grows. The current set covers WebGL shaders and Canvas2D particle systems; the natural next step is custom shaders supplied by the page itself.