1. What your browser reports
Support for random():
Checking...
Reading it live with CSS.supports.
2. The demo: a scatter with no positions written
No dot on that stage has a position written for it individually. Where random() is supported, the stylesheet rolls each dot's position, size, corner radius, rotation, and hue, per element, fresh on every page load. Reload the page and the field changes. Where it is not supported yet, a small script does the same rolls so the stage still shows what the CSS will do, and the label above tells you honestly which one you are looking at.
3. The pattern
One rule does the whole stage. Each dot that matches gets its own values:
.dot {
left: random(2%, 90%);
top: random(4%, 82%);
width: random(10px, 28px);
height: random(10px, 28px);
border-radius: random(25%, 50%);
rotate: random(-35deg, 35deg);
background: hsl(random(248, 292) 85% 68%);
}
Two things worth knowing. The arguments must agree on type: percentages with percentages, pixels with pixels. And the optional first argument is a sharing key. Leave it off and every call rolls independently. Give several calls the same key, like random(--seed, 0, 360), and they share one roll, which is how you keep a width and a height in step, or a hue consistent across elements.
4. Honest notes
- One stable browser today. Safari 26.2 is the only stable browser shipping
random(), and even there the support is partial. Chrome has it behind the experimental web platform features flag in Chromium builds, not in stable. Firefox does not have it. - The spec can still move.
random()lives in CSS Values and Units Level 5, still an Editor's Draft. The sharing-key syntax is the part most likely to shift. - Random is not a design tool by itself. Rolls can collide, overlap text, or land a low-contrast color on a busy background. Keep it on decoration, in bounded ranges, the way this stage does.
- It composes with the usual care. A static scatter like this one moves nothing, so reduced-motion users get the same still picture as everyone else.