Random Numbers in CSS

From JavaScript workarounds to the new native random() function--learn how to generate unpredictable, dynamic layouts with CSS

CSS has historically lacked the ability to generate random values, forcing developers to rely on JavaScript, preprocessors, or clever workarounds to introduce unpredictability in their designs. This limitation meant that truly dynamic, randomly-generated layouts required runtime JavaScript or build-time preprocessing that didn't persist across page loads.

The CSS Working Group has been addressing this gap, and while full browser support is still emerging, the solution is on the horizon with the new random() function. Understanding both the current workarounds and the upcoming native solution positions developers to leverage randomness in CSS effectively, whether they're building animated interfaces, procedurally-generated layouts, or interactive experiences that feel fresh on each visit.

Understanding the CSS random() Function

The random() function represents a significant advancement in CSS capabilities, allowing developers to generate random numeric values directly in their stylesheets without JavaScript intervention. This function operates similarly to JavaScript's Math.random() but with a key difference: it returns values within a specified inclusive range, giving developers precise control over the randomness they introduce.

CSS random() function syntax
/* Basic random value between 10px and 50px */
width: random(10px, 50px);

/* Random value in increments of 5px */
width: random(10px, 50px, by 5px);
/* Possible values: 10px, 15px, 20px, 25px, 30px, 35px, 40px, 45px, 50px */

The function accepts a minimum value and maximum value as required parameters, defining the boundaries from which the random value will be selected. An optional third parameter enables developers to specify step values, allowing random values to be generated in discrete increments rather than continuous decimals. This proves particularly useful when you need round numbers or specific intervals, such as pixel-aligned positions or standard animation durations.

The generated values recalculate on each page load, meaning users who refresh will see a different arrangement each time. This behavior distinguishes CSS random() from preprocessor random functions, which generate a value once during compilation and maintain that value across all page views until the stylesheet is recompiled.

A critical constraint is that all arguments must use consistent units. You cannot mix length units like rem and em or combine length units with other unit types like percentages. The function requires that minimum, maximum, and step values all share the same dimensional type, though they can use different numeric representations within that type.

Shared Randomness Patterns

One of the most powerful aspects of the CSS random() function is its ability to share randomness across multiple declarations, enabling developers to coordinate random values across different properties or elements. This capability addresses a common need: ensuring that related properties use the same random value while still allowing different properties to use different random values within the same element.

Named Idents for Element-Local Sharing

Named idents provide a mechanism for sharing a random value across multiple random() calls within the same element. By prefixing an ident with -- (similar to CSS custom properties) and using that ident in multiple random() function calls, all instances will receive the same random value while generating different values for different elements.

Named idents for shared randomness
.random-square {
 width: random(--size, 100px, 200px);
 height: random(--size, 100px, 200px);
}

In this example, each element receives its own random size value, but both width and height for that element use the same randomly-generated number. If you have ten elements, each will have a different random size, but within each element, the width and height will match perfectly, creating squares rather than rectangles.

Element-Shared for Cross-Element Coordination

The element-shared keyword takes shared randomness a step further, allowing all elements matching a selector to receive identical random values for a given property. This proves valuable when you want multiple elements to share a coordinate, rotation angle, or other property value while maintaining different values for other properties.

Element-shared for coordinated elements
.shared-random-rect {
 width: random(element-shared, 100px, 200px);
 height: random(element-shared, 100px, 200px);
}

All elements with the shared-random-rect class will have identical width and height values, creating visually coordinated elements. However, these values will differ from any other random declarations not using the element-shared keyword. Advanced use cases can combine both approaches for sophisticated randomness patterns.

Practical Applications and Examples

The ability to generate random values in CSS opens numerous creative possibilities, from procedural design patterns to interactive animations. Understanding common application patterns helps developers recognize opportunities to leverage randomness effectively in their projects.

Procedural Layout Generation

Random positioning enables entirely new approaches to layout design, where elements appear at unpredictable locations rather than following predetermined grid structures. This technique proves particularly effective for decorative elements, particle effects, and artistic compositions where organic variation enhances the visual impact.

Procedural starfield with random positioning
.star {
 position: fixed;
 top: random(0%, 100%);
 left: random(0%, 100%);
 width: random(2px, 6px);
 height: random(2px, 6px);
}

Each star receives a unique position within the viewport and a variable size, creating depth and visual interest. The fixed positioning ensures elements remain anchored relative to the viewport rather than document flow, allowing natural-looking distributions across the page. This creates a starfield that differs with each page load.

Animation Variability

Random animation properties prevent the mechanical repetition that can make animated interfaces feel artificial. By introducing variation in duration, delay, and easing, individual animations appear more organic and less synchronized.

Random animation durations and delays
.card {
 animation-duration: random(1s, 3s);
 animation-delay: random(0s, 2s);
 animation-iteration-count: infinite;
}

The random duration ensures cards don't flip in perfect synchronization, while random delays stagger the start times across the collection. This subtle variation creates a more dynamic, engaging visual experience. Random animation properties prevent the mechanical repetition that can make animated interfaces feel artificial.

Current Workarounds and JavaScript Integration

While native CSS random() support develops, developers have created several approaches to achieve similar effects using existing technologies. Understanding these workarounds helps developers choose appropriate solutions for projects that must support current browsers. For teams working with our web development services, we typically recommend progressive enhancement strategies that gracefully fall back to JavaScript-based solutions in unsupported browsers.

CSS Custom Properties with JavaScript

The most common approach combines CSS custom properties with JavaScript to inject random values at runtime. This method provides full browser compatibility and predictable behavior across all modern browsers.

JavaScript random value injection
document.documentElement.style.setProperty(
 '--random-x', 
 Math.random() * 100 + '%'
);
CSS using custom property
.element {
 left: var(--random-x);
}

This approach requires JavaScript execution but offers complete control over when and how random values are generated. Developers can regenerate values on demand, in response to user interactions, or on page load. The trade-off is the dependency on JavaScript execution, which might not be suitable for all use cases or environments.

An alternative approach is the Cicada Principle, which leverages the fact that CSS animations with different durations naturally fall in and out of synchronization over time, creating apparent randomness without actual random value generation. By using prime numbers for animation durations, developers can maximize the period before patterns repeat.

Browser Support and Implementation Status

The CSS random() function exists as a working draft specification with evolving implementation support. Understanding the current status helps developers make informed decisions about when and how to adopt this new capability. Our web development team actively tracks these specifications to ensure we can leverage new features as browser support matures.

Progressive enhancement pattern
.element {
 position: fixed;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
 transform: translate(
 calc(-50% + random(-50px, 50px)), 
 calc(-50% + random(-50px, 50px))
 );
}

For production projects, the recommended approach combines progressive enhancement with fallback strategies. In unsupported browsers, the second transform rule is ignored, leaving the element centered. In supported browsers, the random offset creates unpredictable positioning while the translation maintains centering relative to the random position.

The CSS Working Group continues refining the specification, addressing questions around usage contexts, interaction with other CSS features, and potential restrictions on where random() can appear. Developers interested in tracking progress should monitor the CSS Values and Units Module Level 5 specification and browser release notes for implementation updates.

Performance Considerations

Generating random values and recalculating layout based on those values has performance implications that developers should consider when incorporating randomness into their designs. The CSS random() function computes values during style calculation, which occurs during rendering but before painting, making it more efficient than JavaScript-based approaches that require layout thrashing. When implementing these techniques as part of our professional web development services, we carefully evaluate performance impact on all target devices.

When using random values to affect layout properties like position or size, browsers must perform layout calculations to determine element placement and dimensions. Frequent changes to random values--particularly through animation or user interaction--can trigger repeated layout operations that impact performance.

Random positioning of fixed or absolutely positioned elements generally performs better than random positioning of in-flow elements, as fixed positioning removes the element from normal document flow and reduces the cascade of layout recalculations. For complex scenes with many randomly-positioned elements, consider using GPU-accelerated properties or compositing techniques to minimize the performance impact.

Best Practices for Randomness in CSS

Effectively using random values in CSS requires balancing creativity with performance and maintainability. Several practices help developers achieve compelling results without introducing problems.

Key Recommendations

Use Descriptive Named Idents

Choose names like `--star-size` that indicate purpose rather than generic identifiers like `--shared-1`

Structure for Future Migration

Encapsulate random value generation in ways that facilitate transition to native random() support

Consider User Experience

Some users may find truly random layouts disorienting--provide options when possible

Test Across Viewport Sizes

Ensure random layouts maintain acceptable behavior across all supported devices

Frequently Asked Questions

Ready to Build Dynamic CSS Experiences?

Our web development team stays ahead of CSS specifications to deliver modern, performant solutions that leverage the latest browser capabilities.

Sources

  1. WebKit: Rolling the Dice with CSS random() - Official WebKit blog announcing the new CSS random() function
  2. CSS-Tricks: random() Function Almanac - Complete documentation of the experimental CSS random() function
  3. CSS-Tricks: Random Numbers in CSS - Classic article on using CSS custom properties with JavaScript
  4. CSS Values and Units Module Level 5 Specification - W3C specification for CSS values including random()