Animation Intermediate

Random values per element without JavaScript

Randomising layout details like rotation, size, or delay used to mean Math.random() in JavaScript and inline style attributes. The CSS random() function generates a random value per element directly in CSS.

Modern
3 lines
1.card {
2  rotate: random(-15deg, 15deg);
3  animation-delay: random(0s, 1s);
4}
Old JS + inline styles
// JS: randomise per element at runtime
1document.querySelectorAll('.card').forEach(el => {
2  const r = Math.random() * 30 - 15;
3  el.style.setProperty('--rotate', r + 'deg');
4  const d = Math.random();
5  el.style.setProperty('--delay', d + 's');
6});
7
8/* CSS reads the inline vars */
9.card {
10  rotate: var(--rotate);
11  animation-delay: var(--delay);
12}
Limited availability 19% global usage

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Not ready for production without a fallback.

18.4+
each card gets its own random rotation
1
2
3
4
5
6
7
8
rotate: random(-20deg, 20deg) β€” per element, no JS
Kinsta

Your first month is free

Managed WordPress hosting for faster sites.

Learn more
⚑

No JavaScript at all

Math.random() plus inline style mutations are gone. The browser picks the value per element automatically.

✦

Per-element by default

Each element gets its own independently drawn value. No loop, no forEach, no dataset juggling.

∞

Works in any property

Use it for rotation, delay, size, color lightness, or any numeric value. Units are respected so you get real CSS values back.

Lines Saved
12 β†’ 3
JS loop gone
Old Approach
Math.random()
JS loop + inline styles
Modern Approach
random(min, max)
Pure CSS, per element

How it works

The random(min, max) function takes a minimum and maximum value and returns a random number in that range. Both values must use the same unit, so random(-15deg, 15deg) gives back an angle, and random(0s, 2s) gives back a time. An optional third argument step snaps the result to a multiple of that step.

By default, each element that uses random() gets its own independent draw. This replaces the common pattern of looping over elements in JS to set a custom property on each one. The browser handles the per-element distinction without any markup changes.

Since this is a CSS Values Level 5 feature, browser support is currently limited to Safari. Use @supports (rotate: random(-1deg, 1deg)) to apply it progressively, with a fixed fallback for other browsers.

New CSS drops.

Join 600+ readers who've survived clearfix hacks.

ESC