In his tie-in book on moral philosophy, How to Be Perfect, Michael Schur—creator of the acclaimed television comedy The Good Place—dedicates a chapter titled “The Luck of the Draw” to exploring the myth of meritocracy. Schur argues that people frequently underestimate the overwhelming role that luck plays in shaping their lives. In a universe where quantum mechanics and philosophical thought alike suggest that chance is fundamental, there is a compelling parallel in modern front-end web development: digital interfaces are increasingly moving away from rigid determinism and embracing controlled chaos.
Web design trends are reflecting this shift toward probabilistic thinking. From subtle layout variations each time a user lands on a page to complex generative user interfaces (GenUI)—such as Google’s proposed integration of generative UI in search—designers are exploring unpredictable user experiences (UX). As ancient philosopher Heraclitus famously observed that one cannot step into the same river twice, developers are discovering the value of web pages that exist in a state of subtle flux. However, extreme applications of nondeterminism remain controversial, with mixed user reactions highlighting the delicate balance between delight and disorienting chaos.
To support this design evolution, web standards bodies and browser vendors have begun taking steps to bring native randomness directly into the presentation layer of the web, sparked by Apple’s Safari browser and carried forward by open-source polyfills.
Real-World Use Cases for Randomness
The drive for controlled presentational randomness is not merely theoretical; it is rooted in practical application requirements. Front-end consultants working on short-term, greenfield corporate projects often observe emerging design trends firsthand. In client applications, randomness frequently manifests in features meant to provide visual reinforcement—such as a burst of animated confetti following a randomized draw feature.
Even a seemingly straightforward UI element like celebratory confetti often exposes the underlying tension between chaos and control in user experience. Corporate branding guidelines frequently demand that every randomized particle conform to specific visual constraints, color palettes, and movement vectors. When existing third-party JavaScript plugins prove too rigid to meet these criteria, engineering teams are often forced to write custom JavaScript implementations to align particle physics with brand requirements.
This tension raises a fundamental question for web engineers: could presentational randomness be handled natively within CSS, eliminating the need to write heavy JavaScript logic for visual effects?
The creators of CSS have long sought to identify recurring UI patterns in the wild and standardize them into declarative CSS specifications—a practice referred to in web standards communities as "paving the cowpaths." In late 2025, Apple’s Safari became the first major browser to ship support for the native CSS random() specification as part of its Safari 26.2 update. The milestone was explicitly aligned with the goal of enabling common layout and presentation solutions using HTML and CSS alone, adhering to the World Wide Web Consortium’s (W3C) Rule of Least Power, which advises solving web development challenges using the least powerful language capable of expressing the solution.
Following Safari’s implementation, web developers and educators began demonstrating the utility of native randomness. Developer Schalk Neethling showed how native CSS random() offers fine-grained control over confetti effects, while web developer Alvaro Montoro argued that CSS is inherently the most appropriate layer for presentational randomness.
However, cross-browser availability remains a challenge. Months after Safari introduced native support, there is little clarity regarding when the feature will ship in other major browsers. While issue trackers for both Google Chrome (Chromium) and Mozilla Firefox indicate active engine development, neither browser vendor has provided guarantees regarding release dates or browser flags. This creates a sharp contrast with historical web development trends, where emerging CSS features typically debuted in Chromium before reaching Safari users.
Let’s Polyfill CSS random()
The standard browser ecosystem timeline has left many developers unable to use native CSS randomness on non-Apple platforms or on older Apple operating systems where browser updates are tied to system releases. To address this gap and allow cross-browser testing today, developers have turned to polyfilling the CSS random() function.
Polyfilling CSS random() presents distinct engineering challenges compared to traditional JavaScript polyfills or selector-based CSS polyfills. The underlying specification—governed by the W3C CSS Values and Units Module Level 5—is currently an editor’s draft in an early exploration phase. The spec defines complex syntax rules, including precise caching semantics, keying mechanisms, base value definitions, and interval step calculations, all of which remain subject to potential breaking changes.
Despite these hurdles, open-source initiatives have produced functional client-side polyfills, such as the css-random-polyfill package. Rather than attempting to introduce non-standard syntax that breaks CSS parsing, this approach leverages standard CSS custom properties (variables) with a dedicated naming convention (--random-*). Because custom properties can hold arbitrary expression values that remain syntactically valid in all modern browsers, JavaScript can read these computed styles at runtime without breaking the browser’s native stylesheet parser.
If native support is detected—as is the case in modern Safari releases—the polyfill naturally yields to the browser’s engine, executing zero JS processing and allowing native C++ web engine implementations to handle the rendering.
Demo: Random Starfield
To demonstrate the capability of native declarative randomness across all browsers, existing Safari-only web demonstrations have been adapted using the polyfilling technique. The first example, adapted from an initial WebKit team preview, features a field of 200 randomly scattered stars that fade in and out at varied timing intervals.
<!-- The script processes usages of CSS random on page load -->
<script src="https://unpkg.com/css-random-polyfill@latest/dist/css-random-polyfill.js"></script>
<!-- Star elements with the "randomized" marker class -->
<div class="randomized star"></div>
<div class="randomized star"></div>
<div class="randomized star fourpointed"></div>
<div class="randomized star fourpointed"></div>
In the CSS, each star element stores its target random metrics within intermediate --random-* properties. The polyfill interprets these functions, calculates the outcome according to the specification guidelines, and assigns the evaluated values.
.star
--random-star-size: random(1px, 7px, 1px);
background-color: white;
border-radius: 50%;
aspect-ratio: 1/1;
width: var(--random-star-size);
position: fixed;
--random-top: random(0%, 100%);
--random-left: random(0%, 100%);
top: var(--random-top);
left: var(--random-left);
--random-hue: random(0, 360);
filter: drop-shadow(0px 0px calc(var(--random-star-size) * 0.7) oklch(0.7 0.2 var(--random-hue)))
drop-shadow(0px 0px calc(var(--random-star-size) * 3) white);
mix-blend-mode: hard-light;
--random-speed: random(2s, 5s);
animation: fade-in var(--random-speed);
animation-iteration-count: infinite;
--random-delay: random(2s, 5s);
animation-delay: var(--random-delay);
animation-direction: normal;
This starfield demo illustrates several syntax variations supported by the CSS Values and Units Level 5 draft, such as step intervals for picking whole unit increments (random(1px, 7px, 1px)), as well as the element-shared keyword, which guarantees that specific subsets of elements share identical random outputs:
.star.fourpointed
--random-rotation: random(element-shared, -45deg, 45deg);
rotate: var(--random-rotation);
While native CSS random() allows inline substitution inside any standard property value (similar to calc() or min()), requiring intermediate custom properties for the polyfill represents a necessary compatibility tradeoff that preserves standard CSS parsing rules across all browsers.
Demo: Random Colored Grid Cells
A second implementation explores mathematical layout structures: a 100×100 CSS grid featuring randomly colored and positioned cells. Prominent web development author Chris Coyier noted that visual declarative demonstrations of CSS random() illustrate how clean presentational logic becomes when removed from JavaScript runtime dependencies.
In this layout, multiple random() calls are chained within shorthand custom properties to control spatial placement across CSS grid lines:
.rectangle
--random-grid-area: random(1, var(--rows), 1) / random(1, var(--columns), 1);
grid-area: var(--random-grid-area);
The polyfill handles variable resolution within the random() parameters, dynamically evaluating variables like --rows and --columns before returning valid calculated grid-area strings.
Demo: Wheel of Fortune
A demonstration crafted by Safari engineer Tim Nguyen highlights how random() manages unit conversions through CSS typed arithmetic rules. In this interactive element, a spinning wheel rotates to a randomized final stopping angle.
@keyframes spin
from
rotate: 0deg;
to
rotate: var(--random-rotation);
#wheel
--random-rotation: random(2turn, 10turn, 20deg);
The specification allows combining differing units—such as turns (turn) and degrees (deg)—within a single random() call, provided all specified arguments resolve to the same underlying dimensional data type (in this case, angle measurements).
The current client-side polyfill architecture evaluates DOM computed styles during initial page load rendering. Dynamic state changes triggered by dynamic CSS selectors or checkbox hacks require subsequent re-evaluation passes, marking an area for future polyfill performance optimization.
Demo: Random Squares
A foundational demo originally written by Chris Coyier illustrates basic spatial distribution across simple geometric shapes. Expanding upon Coyier’s base code, key-based random value sharing can be validated.
--random-height: random(--side, 40px, 100px);
--random-width: random(--side, 40px, 100px);
width: var(--random-height);
height: var(--random-width);
By providing a matching custom key identifier (--side), the specification mandates that separate declarations must resolve to identical calculated values for the target element, ensuring that generated rectangles retain perfect 1:1 square aspect ratios without explicit CSS aspect-ratio properties.
Chromium-Only Bonus Demo: Simulate random-item Using a Custom CSS Function
Beyond numerical ranges, web authors frequently require random selection from explicit discrete sets, such as picking a color from a brand palette. The CSS draft spec proposes a dedicated random-item() function for this purpose, though browser support remains limited to experimental builds such as Safari Technology Preview 251.
However, in Chromium environments where support for experimental CSS Custom Functions (@function) and inline style conditionals (if()) is enabled, authors can construct functional abstractions that approximate random-item() logic directly in CSS:
--random-index: random(element-shared, 1, 5, 1);
--random-color: --item(var(--random-index), aqua, purple, pink, grey, green);
This custom function accepts an index parameter alongside optional arguments. Using CSS inline conditional logic, it maps the computed numerical index to the matching item in the list:
@function --item(--index,
--arg-1: ,
--arg-2: ,
--arg-3: ,
--arg-4: ,
--arg-5: ,
--arg-6: ,
--arg-7: ,
--arg-8: ,
--arg-9: ,
--arg-10: )
result: if(
style(--index: 1): var(--arg-1);
style(--index: 2): var(--arg-2);
style(--index: 3): var(--arg-3);
style(--index: 4): var(--arg-4);
style(--index: 5): var(--arg-5);
style(--index: 6): var(--arg-6);
style(--index: 7): var(--arg-7);
style(--index: 8): var(--arg-8);
style(--index: 9): var(--arg-9);
else: var(--arg-10);
);
Unlike historical CSS array hacks—such as those created by CSS author Temani Afif, which relied on specialized color math tricks—combining custom functions with CSS conditionals creates a type-agnostic mechanism capable of picking strings, lengths, colors, or keywords from structured lists.
How the Polyfill Works
The architecture of css-random-polyfill relies heavily on open-source web standards tooling developed by CSSTools. Specifically, the polyfill wraps @csstools/css-calc, an open-source mathematical parsing engine originally built for build-time PostCSS transformations.
When loaded into a non-supporting browser environment, the polyfill executes a specific sequence to resolve declarative randomness without causing rendering artifacts or layout thrashing.
First, the script evaluates platform capabilities using the native CSS.supports() API, checking whether the browser natively understands expressions like CSS.supports("width", "random(0px, 100px)"). If native support is present, execution halts immediately to prevent unnecessary client runtime overhead.
If the feature is un-supported, the polyfill temporarily injects a dynamic standard style tag into the document head containing .randomized display: none; . This temporarily hides marked target elements to prevent visual layout shifts (Flash of Unstyled Content) while calculation occurs.
The polyfill establishes tracking context by instantiating a unique document session identifier via crypto.randomUUID(), while assigning a JavaScript WeakMap to manage element-level lifetime bindings. It then performs a DOM query across target selectors (.randomized), evaluating computed styles via getComputedStyle().
From these computed styles, the script filters all custom property declarations prefixed with --random. The raw property string is passed into a evaluation method (resolveRandom), where unseeded random() calls are normalized with explicit deterministic evaluation seeds (fixed [seed]).
import calc from "@csstools/css-calc";
const calcFn = calc;
if (!CSS.supports("width", "random(0px, 100px)"))
const styleTag = document.createElement("style");
styleTag.textContent = ".randomized display: none; ";
document.head.appendChild(styleTag);
const elementIDs = new WeakMap();
const documentID = crypto.randomUUID();
document.querySelectorAll(".randomized").forEach((element) =>
const styles = getComputedStyle(element);
[...styles]
.filter((property) => property.startsWith("--random"))
.forEach((propertyName) =>
const css = styles.getPropertyValue(propertyName);
const value = resolveRandom(css,
element,
propertyName,
documentID,
elementIDs,
calcFn,
crypto,
);
element.style.setProperty(propertyName, value);
);
);
if (styleTag.parentNode)
styleTag.parentNode.removeChild(styleTag);
function resolveRandom(css, element, propertyName, documentID, elementIDs, calcFn, crypto ) --))([^,]+),/gi,
(_, expression) => `random(fixed $Math.random(), $expression,`
);
return calcFn(patchedCss,
precision: 5,
toCanonicalUnits: true,
randomCaching:
documentID,
elementID: elementIDs.getOrInsert(element, `element-$crypto.randomUUID()`),
propertyName,
,
);
The underlying @csstools/css-calc engine parses the mathematical expressions, accounts for unit conversions, enforces step boundaries, resolves variable scopes, and returns concrete canonical CSS units. The polyfill then writes these finalized values back to the element’s inline styles using element.style.setProperty(), finally removing the dynamic hiding style rule from the document DOM to reveal the computed layout.
By relying entirely on valid CSS custom properties, this execution pattern avoids the primary pitfalls of legacy CSS polyfilling—such as re-fetching raw external CSS files, parsing full CSS syntax trees in JavaScript, or manually overriding browser cascading logic.
Random Parting Thoughts
The arrival of native declarative randomness through CSS random() represents a meaningful step in the evolution of front-end web standards. By standardizing presentational nondeterminism, web specifications are enabling complex visual behaviors—from organic particle effects to probabilistic layouts—without requiring modern applications to rely heavily on JavaScript runtime utilities.
While full native support across Chromium and Firefox remains on browser vendor roadmaps, community polyfills leverage existing open-source parsing tooling to make these declarative patterns testable across production environments today. As browser engines continue alignment around the W3C CSS Values and Units Level 5 specifications, declarative randomness is poised to transition from an experimental visual effect into a standard capability for modern web interfaces.