Generating designs in the style of Josef Albers’ Homage to the Square — nested, offset squares in a random gradient, a new composition every few seconds, finished with a soft grain. Built in p5.js, first as a 2021 experiment.
🟧 Albers’ Squares
2026.09.12 updated 2026.09.13
Homage to the Square, generated
Readme
A p5.js sketch that generates designs in the style of Josef Albers' Homage to the Square: nested, offset squares filled with a random gradient, a new composition every few seconds, finished with a soft grain.
From a 2021 experiment, rebuilt as a self-contained static page.
Run it
Open index.html in a browser, or serve the folder:
python3 -m http.server
p5 loads from a CDN; everything else is in sketch.js.
What's here
index.html— the page: loads p5 and the sketch, and starts it.sketch.js— the sketch.setColorsbuilds the palette,createSquaresstacks the nested squares, and a generated grain is soft-light blended on top. The original overlaid acanvas.jpgtexture that was lost; the grain stands in for it.
One copy of the sketch
sketch.js does not start itself. It puts an instance-mode factory on
window.albersSketch and stops there, so the page that loads it decides when to
run it and keeps the handle to stop it again:
const instance = new p5(window.albersSketch, document.getElementById('albers-container'));That is what index.html does here, and it is what the Albers post on
bobbymeyer.com does too — it loads this same file from this deploy rather than
keeping a copy of its own, and tears its instance down when the site's client
router navigates away. The post used to carry a second copy, and the two drifted
the first time the palette changed. Anything that would break that call —
renaming the global, starting the sketch from this file, needing a p5 the post
does not load — breaks the post, so it is worth a thought before changing.
About the palette
The first version lerped between two independently random RGB colours, which
regularly landed two touching squares close enough to merge — a four-square
composition would read as two or three. The palette is now built in
OKLab, where a step in lightness is
roughly a step in what the eye sees, so neighbouring squares can be held at
least MIN_STEP apart in lightness. L_FLOOR and L_CEIL keep the ramp off
the ends where a screen crushes everything to black or white, and only chroma
is ever trimmed to fit sRGB — which leaves those lightness gaps intact on the
canvas. A composition can still come out dark, pale or near-grey; it just
cannot come out with fewer squares than it has.
MIN_SQUARES and MAX_SQUARES set how many squares a composition stacks —
3 to 5, picked evenly.