Retour au blogDéveloppement

random() en CSS : générer de l'aléatoire natif sans une ligne de JavaScript

CZSyn
9 juillet 2026
6 min

La fonction CSS random() sort de l'expérimentation : syntaxe, piège des custom properties et support Chromium, Safari, Firefox en juillet 2026.

Un nuage de cercles lumineux colorés façon bokeh, générés par un effet CSS aléatoire, sur fond sombre
Ce qu'il faut retenir
  1. La fonction CSS random() calcule une valeur aléatoire directement dans une propriété (position, taille, couleur, opacité) sans JavaScript, mais une custom property random() se réévalue à chaque lecture : width et height peuvent recevoir deux nombres différents.
  2. Le mot-clé element-scoped fige une seule valeur aléatoire par élément (il sera renommé per-element dans la spécification) : c'est ce qui permet à un cercle d'avoir une largeur et une hauteur identiques.
  3. État du support en juillet 2026 : Chromium 148+ derrière le flag Experimental Web Platform Features, Safari 26.2+ en partiel, aucun support dans Firefox. Le navigateur de test Polypane (v29+) l'implémente entièrement pour prototyper avant l'arrivée du support généralisé.

Résumé généré par IA

La fonction CSS random() sort progressivement du statut d'expérimentation. Chromium 148 la supporte derrière le flag « Experimental Web Platform Features », Safari 26.2 en propose un support partiel, et Polypane, l'éditeur d'un navigateur de test dédié aux développeurs front, vient de publier une série de démonstrations qui montre ce que cette fonction permet de faire sans écrire une seule ligne de JavaScript.

Jusqu'ici, générer un effet visuel aléatoire (un fond façon bokeh, une pluie de pétales, une pile de photos posées de travers) obligeait à passer par JavaScript : un Math.random() dans une boucle, puis une injection de style inline ou de custom properties calculées à la volée. Avec random(), cette logique peut vivre directement dans la feuille de style. Moins de JavaScript à charger et à exécuter, moins de code à maintenir pour un effet qui reste purement cosmétique. On décortique la syntaxe, un piège réel qu'il faut connaître avant de s'en servir, et l'état du support navigateur.

Ce que fait random(), concrètement

La syntaxe de base est simple : random(min, max) renvoie un nombre aléatoire compris entre les deux bornes. Pour positionner des cercles aléatoirement dans un conteneur (l'exemple du bokeh utilisé par Polypane pour présenter la fonction), il suffit d'écrire :

.bokeh {
  position: absolute;
  left: random(0%, 100%);
  top: random(0%, 100%);
  border-radius: 100%;
}

random(0%, 100%) tire une valeur entre 0 et 100 %. Attention au typage : les deux bornes doivent partager la même unité. random(0, 100%) est invalide, puisque le minimum est un nombre et le maximum un pourcentage. Il faut écrire random(0%, 100%).

Le piège des custom properties

Pour donner une taille aléatoire à chaque cercle tout en gardant une forme circulaire, le réflexe naturel est de stocker la valeur dans une custom property et de la réutiliser pour la largeur et la hauteur :

.bokeh {
  --size: random(50px, 20vmin);
  width: var(--size);
  height: var(--size);
}

Résultat surprenant à la première utilisation : la largeur et la hauteur sont différentes. En CSS, une custom property qui contient random() génère une nouvelle valeur à chaque endroit où elle est lue, pas seulement au moment où elle est déclarée. Le correctif est un mot-clé dédié, element-scoped, qui fige une seule valeur aléatoire pour tout l'élément :

.bokeh {
  --size: random(element-scoped, 50px, 20vmin);
  width: var(--size);
  height: var(--size);
}

Précision utile si vous testez ça dans les mois qui viennent : element-scoped n'est pas le nom définitif du mot-clé. Il sera renommé per-element dans la spécification. Aucun des deux noms n'est encore figé sur MDN, même si une proposition de documentation a déjà été soumise.

calc() pour ne pas déborder du conteneur

Reste un souci de positionnement : un cercle placé à 99 % depuis la gauche avec une taille de 100px déborde du conteneur et déclenche des barres de défilement parasites. La solution consiste à soustraire la taille du cercle à la borne maximale avec calc() :

.bokeh {
  left: random(0%, calc(100% - var(--size)));
  top: random(0%, calc(100% - var(--size)));
  --size: random(element-scoped, 50px, 20vmin);
  width: var(--size);
  height: var(--size);
}

Comme --size ne prend qu'une seule valeur par élément grâce à element-scoped, elle reste identique dans les trois propriétés. La position se cale donc sur la taille réelle du cercle, sans jamais dépasser le conteneur.

Couleur et opacité aléatoires

Même logique pour donner à chaque cercle une teinte et une visibilité différentes, en combinant random() avec hsl() :

.bokeh {
  background: hsl(random(0, 360) 80% 50%);
  opacity: random(0.1, 1);
}

La teinte dans hsl() est un nombre, donc pas besoin d'unité pour le premier argument de random(). Même chose pour l'opacité. En quatre propriétés, un fond de bokeh entièrement aléatoire tient dans une seule règle CSS, sans script ni génération de balisage côté serveur.

Ce que la spécification prévoit en plus

L'article de Polypane va plus loin avec des démonstrations utilisant random-item() pour piocher une valeur dans une liste discrète (utile pour varier des styles de mise en page texte par texte), une valeur de pas (« step ») à l'intérieur de random() pour caler le résultat sur une grille de valeurs plutôt qu'un continuum, et des valeurs aléatoires pondérées pour favoriser certains résultats plutôt que d'autres. Ces briques sont encore moins stabilisées que random(min, max) et element-scoped, donc mieux vaut consulter directement la démonstration source avant de les utiliser en production.

Le support navigateur en juillet 2026

  • Chromium 148+ : supporté derrière le flag « Experimental Web Platform Features », à activer manuellement dans chrome://flags.
  • Safari 26.2+ : support partiel. Plusieurs démonstrations de l'article source ne fonctionnent pas encore correctement sur ce moteur.
  • Firefox : aucun support à ce jour.
  • Polypane 29+ : implémentation la plus complète actuellement, dans un navigateur pensé pour les développeurs plutôt que pour le grand public.

Concrètement, tant que Firefox n'a pas embarqué la fonction, aucun effet construit avec random() ne doit porter une information ou une interaction essentielle. C'est un outil pour de l'habillage visuel progressif, pas encore pour de la logique d'interface.

Notre lecture chez CZSyn

Ce que nous retenons de cette fonction, au-delà de l'effet de démonstration : elle confirme une tendance de fond que nous observons sur les projets de nos clients depuis deux ans, à savoir le CSS qui absorbe des comportements qui exigeaient jusqu'ici du JavaScript (animations pilotées par le scroll, sélection avec :has(), et maintenant l'aléatoire). Chaque brique qui bascule côté CSS, c'est un peu moins de JavaScript à télécharger, parser et exécuter sur le poste du visiteur, donc un gain direct sur les métriques de performance qui pèsent sur le référencement.

Pour autant, avec Firefox toujours sans support et Safari en partiel, nous ne recommandons pas encore random() pour une PME qui a besoin que son site s'affiche de façon identique chez tous ses visiteurs. En revanche, c'est le bon moment pour l'essayer sur des éléments strictement décoratifs : un fond de page d'accueil, un écran de chargement, une page d'erreur 404, où un rendu figé (une position ou une teinte par défaut au lieu d'un aléatoire) en cas d'absence de support ne casse rien pour l'utilisateur. C'est exactement le genre d'amélioration progressive que nous mettons en place sur les sites que nous développons.

Envie d'un site qui exploite le CSS moderne sans plomber vos performances ?

Nous auditons vos pages pour repérer les scripts JavaScript remplaçables par du CSS natif, et développons des interfaces sur-mesure prêtes pour les navigateurs de demain. Audit gratuit sous 24h.

29 AVIS 5/5 · +200 PROJETS LIVRÉS · RÉPONSE EXPRESS

Sources primaires

Un projet en tête ?

Discutons de votre projet et voyons comment nous pouvons vous aider.

Nous contacter