In his book How to Be Perfect, Michael Schur, the creator of the acclaimed television series The Good Place, devotes a chapter titled "The Luck of the Draw" to exploring how the myth of meritocracy leads individuals to underestimate the role chance plays in their lives. The notion that unpredictable forces shape our reality has long captured the human imagination, from ancient philosophical musings—such as Heraclitus’s observation that one cannot step into the same river twice—to modern physics and computer science.
In recent years, art has increasingly imitated life on the web as digital designers embrace controlled non-determinism. Web pages are moving away from rigid, static layouts toward dynamic interfaces that exist in a state of subtle flux each time a user visits. While extreme iterations of this trend, such as generative user interfaces in search platforms, have sparked debate among users cautious about unpredictable navigation, presentational randomness offers an undeniable charm when applied thoughtfully to interface design.
Real-world use cases for randomness
For web developers and front-end consultants working on short-term, greenfield projects, emerging design trends frequently dictate client requirements. Corporate projects are increasingly incorporating controlled chaotic elements to heighten user engagement. A common real-world example is the custom confetti animation—a visual burst designed to grant users a sense of celebration when triggering a randomized prize draw or completing an action.
Even seemingly simple decorative features face significant design demands in enterprise environments. Brand guidelines often require that every randomized particle align precisely with corporate aesthetics. In many development workflows, generic off-the-shelf JavaScript plugins fall short of these custom requirements, forcing engineering teams to write custom confetti implementations.
This friction highlights an ongoing challenge in modern user experience design: the tension between the desire for spontaneous visual variety and the imperative for absolute stylistic control. For years, resolving this tension required complex JavaScript calculations to handle purely visual randomness. Front-end engineers have long argued that such presentational tasks belong naturally in the presentation layer, sparking interest in whether declarative CSS could manage controlled randomness directly without relying on heavy scripts.
If unpredictable user experiences are gaining traction, web standards must adapt to make randomized layouts easy to author. Historically, the maintainers of the CSS specification have aimed to codify common UI patterns into native declarative standards—a philosophy often described 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 celebrated as part of a broader effort to allow developers to build complex visual interfaces using native HTML and CSS alone, drastically reducing reliance on external JavaScript utility libraries.
Since Safari’s initial release, the developer community has enthusiastically demonstrated the capabilities of declarative randomness. Web developer Schalk Neethling showcased how native CSS random() provides fine-grained control over randomized confetti animations, while author Alvaro Montoro emphasized that CSS is the ideal language for presentational randomness. Montoro noted that shifting randomness into CSS aligns with the web’s "Rule of Least Power," an architectural principle encouraging developers to solve problems using the least complex programming language capable of achieving the desired outcome.
However, browser fragmentation presents a major hurdle. Half a year after Safari introduced native CSS random(), cross-browser availability remains constrained. While engineering tracks in Chromium (for Google Chrome) and Bugzilla (for Mozilla Firefox) show active development, neither vendor has committed to a definitive timeline for public release, even behind experimental feature flags.
This browser disparity leaves developers in a frustrating dilemma. While native online demos can be viewed on modern Apple hardware, cross-platform environments and non-Apple workstations remain left out. Furthermore, adopting the native syntax directly poses risks: CSS random() remains part of an Editor’s Draft within the W3C CSS Values and Units Module Level 5, an early-stage specification subject to potential breaking changes. Coupled with intricate specification rules regarding random value caching, keying semantics, step intervals, and base values, writing stable cross-browser code requires a careful approach.
Let’s polyfill CSS random()
To bridge this operational gap between browser support and developer demand, a community-driven solution has emerged in the form of css-random-polyfill. This open-source JavaScript package allows developers to write declarative random() functions today that function consistently across Chrome, Firefox, and legacy versions of Safari.
The necessity for a polyfill highlights an unusual role reversal in browser feature rollouts. Developers are accustomed to seeing experimental web standards launch first in Chromium-based browsers before making their way to WebKit. With CSS random(), the reverse occurred, creating a situation where non-Mac desktop users and Android mobile users were unable to view native experiments. Furthermore, because Safari updates are bundled directly with Apple operating system updates, even Mac and iOS users on older OS versions cannot run native random() without polyfills.
Despite the fragmentation, open-source transparency within the WebKit engine has made it easier for developers to inspect Safari’s underlying implementation. Many of the initial tests and cross-browser demonstrations built for the css-random-polyfill library were directly adapted from original proof-of-concept experiments published by Apple’s WebKit development team.
Demo: Random starfield
One of the most visually compelling early demonstrations created by the Safari team is a animated starfield. The visual features a dense field of small twinkling stars that fade in and out at randomized time intervals. Interspersed among them are larger four-pointed stars, all tilted at a shared, randomly selected rotation angle, with each star casting a subtle, randomly hued drop-shadow.
To adapt this demonstration for universal browser compatibility, developers can integrate the css-random-polyfill script into their documents and mark target elements with a specific .randomized marker class.
<!-- 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 marked with the randomized class for polyfill targeting -->
<div class="randomized star"></div>
<div class="randomized star"></div>
<div class="randomized star fourpointed"></div>
<div class="randomized star fourpointed"></div>
Unlike polyfills that attempt to invent non-standard CSS selectors—which often require complete stylesheet parsing and runtime string translation—the css-random-polyfill operates on standard CSS property values. Modern browser engines parse custom CSS properties without throwing errors, even if they contain unfamiliar functional expressions like random().
To maintain broad compatibility, developers store randomized calculations within intermediate CSS custom properties prefixed with --random.
.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) infinite;
--random-delay: random(2s, 5s);
animation-delay: var(--random-delay);
This starfield example highlights key aspects of the W3C specification syntax. The random(1px, 7px, 1px) declaration uses an optional third argument to define a step interval, restricting values strictly to whole integer step increments.
Additionally, the four-pointed stars utilize the element-shared keyword parameter:
.star.fourpointed
--random-rotation: random(element-shared, -45deg, 45deg);
rotate: var(--random-rotation);
The element-shared keyword instructs the browser engine (or polyfill) to calculate a single random rotation value and apply that exact same angle consistently across all matching four-pointed star elements on the page.
While native CSS allows random() functions to be placed inline directly inside standard property values, requiring temporary custom properties represents a minor tradeoff for polyfill stability. Importantly, because the syntax complies with the draft standard, developers can seamlessly remove the polyfill script once native browser support reaches global baseline availability. When loaded in Safari versions with native support, the polyfill steps aside entirely and allows the browser engine to handle computations natively.
Demo: Random Colored Grid Cells
Industry commentators, including web developer Chris Coyier, praised the visual impact of early native CSS random() demos. While animated starfields illustrate expressive visual potential, practical testing also demands evaluating extreme performance scenarios, such as massive structural grids.
In a test featuring a 100×100 CSS grid populated with hundreds of multi-colored cells, the polyfill demonstrated its ability to resolve nested variable references and multiple inline parameters. For instance, developers can assign dynamic positioning across grid rows and columns using inline grid-area properties:
.rectangle
--random-grid-area: random(1, var(--rows), 1) / random(1, var(--columns), 1);
grid-area: var(--random-grid-area);
This tests the polyfill’s capability to evaluate variable parameters dynamically before resolving final positioning, proving that complex layout math can be executed reliably outside native environments.
Demo: Wheel of fortune
Another notable example adapted for cross-browser evaluation comes from Tim Nguyen, a developer on Apple’s Safari engineering team who presented on modern CSS capabilities at the Web Directions 2025 conference. Nguyen created a interactive "Wheel of Fortune" demo to demonstrate mixed unit handling in native CSS arithmetic.
In this demonstration, the final resting position of a spinning wheel is dictated by randomized rotations across full turns and fractional angular degrees:
@keyframes spin
from
rotate: 0deg;
to
rotate: var(--random-rotation);
#wheel
--random-rotation: random(2turn, 10turn, 20deg);
The standard specification dictates that unit parameters inside random() are valid as long as they can be resolved to a shared underlying data type. Here, turn units and deg (degree) units share an angular dimension, allowing browser math engines to perform typed arithmetic calculations seamlessly.
Under the current implementation of css-random-polyfill, CSS variables are calculated against computed styles applied when the DOM DOM content initially renders. While dynamic animation keyframes initially required minor restructuring to work with static style evaluations, the polyfill successfully handles complex angular calculations without performance degradation.
Demo: Random squares
In a minimalist demonstration inspired by Chris Coyier, three simple square elements are rendered with randomized sizes, positions, and background colors. This example serves as a clean test case for verifying CSS random value sharing through custom key identifiers.
To force a square element to maintain a 1:1 aspect ratio while picking a random size range between 40 and 100 pixels, developers can assign a custom identifier parameter (--side):
--random-height: random(--side, 40px, 100px);
--random-width: random(--side, 40px, 100px);
width: var(--random-height);
height: var(--random-width);
By specifying the matching --side key name as the first argument, the polyfill guarantees that both property evaluations yield identical values for a given element instance. This preserves aspect ratios while retaining procedural variation across separate elements.
Chromium-only bonus demo: Simulate random-item using a custom CSS function
While standard random() functions excel at selecting values from numerical ranges, web developers frequently need to select non-numeric design tokens—such as picking a random color string from a predefined brand palette.
To address this need, the W3C CSS Values and Units Module Level 5 introduced a draft proposal for a random-item() function:
/* Draft specification syntax */
color: random-item(element-shared, red, blue, green);
Because random-item() remains unimplemented across main browser channels, developers working within modern Chromium browsers can combine native experimental CSS features to simulate the functionality today. By pairing random() calculations with emerging Chromium features like CSS custom functions (@function) and inline conditional logic (style()), developers can build discrete selection lookup tables:
--random-index: random(element-shared, 1, 5, 1);
--random-color: --item(var(--random-index), aqua, purple, pink, grey, green);
The supporting custom CSS function maps numerical index inputs to corresponding function argument slots:
@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);
);
Earlier attempts to create color arrays in CSS required complex mathematical hacks constrained strictly to hex or RGB color spaces, as popularized by CSS authors like Temani Afif. In contrast, leveraging experimental @function definitions provides a flexible structure capable of indexing arbitrary design tokens, from string keywords to complex gradient definitions.
How the polyfill works
Building a client-side polyfill for emergent CSS specifications often carries significant maintenance overhead. Rather than constructing a standalone CSS parser from scratch, css-random-polyfill achieves high performance by tapping into established open-source tooling.
The polyfill relies on @csstools/css-calc, an open-source mathematical parsing library maintained by the CSSTools organization. Originally designed to power build-time PostCSS transformations via @csstools/postcss-random-function, the engine was updated to support the latest W3C CSS random() specification updates, including keying, scoping, and custom step resolutions.
The client-side integration follows an efficient execution process:
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);
When a user visits a page, the polyfill first runs a feature check using CSS.supports(). If native support for random() is detected, the script terminates immediately, avoiding unnecessary execution overhead.
If the browser lacks native support, the polyfill injects a temporary style rule hiding .randomized elements to prevent flash-of-unstyled-content (FOUC) artifacts during script evaluation. It generates a unique document execution identifier using crypto.randomUUID().
Next, the polyfill queries all elements marked with the .randomized target class. It inspects their computed styles using getComputedStyle(), filtering specifically for properties starting with the --random naming prefix.
For each custom property string, the script applies cache-key patches and passes the string expression into @csstools/css-calc. The engine processes math units, handles interval rounding, resolves shared scope keys via internal WeakMap element tracking, and returns a computed standard CSS value string.
Finally, the script writes the calculated values back onto the element’s inline style declarations via style.setProperty(), removes the temporary visibility control style tag, and renders the randomized layout.
This architecture leverages the browser’s native property parsing. Because modern CSS engines allow arbitrary text values within custom properties, developers can safely author random() expressions inside variable declarations without causing browser parsing errors. This eliminates the need to re-fetch raw external CSS stylesheets or parse full CSS object models in JavaScript—avoiding two of the most significant performance pitfalls historically associated with front-end polyfills.
Random parting thoughts
The arrival of native declarative randomness represents a significant step in the evolution of modern web styling. By transitioning presentational logic from heavy JavaScript dependencies into native CSS standards, front-end developers gain a cleaner, highly performant toolset for crafting visual variety.
While complete cross-browser baseline status for CSS random() remains an ongoing work in progress across major browser vendors, open-source initiatives like css-random-polyfill provide a reliable path forward. Development teams no longer need to defer creative design ideas while waiting for upstream engine updates. Through modern web standards and pragmatic polyfills, controlled chaos is becoming accessible to web applications everywhere.