
Throwing Confetti with CSS Random
Schalk Neethling builds a 50-piece, zero-JavaScript confetti field using the still-experimental random() function, available in Safari 26.2+ and Chrome 148+ (behind enable-experimental-web-platform-features); Firefox has no support as of July 13, 2026. The key mental model is the random cache name — a tuple of an optional <dashed-ident>, the element, and the document — which makes values a deterministic lookup rather than a per-paint roll, explaining why the confetti reshuffles on reload but holds position through style recalculations. An unregistered custom property stores the random() text and evaluates it at each var() substitution site, so a property read twice yields two different numbers unless an explicit name is given. The portable fallback pattern wraps defaults and :nth-child rules inside @layer fallback so the unlayered @supports block always wins on layer priority — avoiding the specificity trap that lets :nth-child(8n+1) silently override the enhancement. Safari discards random() inside @property-registered custom properties, a divergence from Chromium that the author documents live.





