La función random()

Generar valores aleatorios en CSS


Una de las grandes limitaciones de CSS era la falta de mecanismos para generar valores numéricos aleatorios sin necesidad de utilizar lenguajes como Javascript de apoyo. En muchas ocasiones necesitamos de estas funciones para generar aleatoriedad en nuestros diseños y conseguir dinamismo como colores aleatorios, tiempos diferentes en animaciones o tamaños variables, por mencionar algunos ejemplos sencillos.

Esta limitación desaparece con la incorporación de funciones CSS como random() o random-item():

FunciónDescripción
random(min, max)Genera un número aleatorio entre min y max.
random-item(val1, val2, ...)Devuelve uno de los valores propuestos al azar.

La función random()

Mediante la función random() podemos generar un valor aleatorio entre dos números. El primer parámetro será el número mínimo y el segundo parámetro el número máximo. Sin embargo, la función random() aunque parece muy sencilla, tiene varios matices importantes que debemos conocer.

En el siguiente ejemplo, la función random() se utiliza dos veces, para dos propiedades CSS diferentes. Pero observa que ambas están usando los mismos parámetros:

.container {
  width: random(100px, 500px);    /* Tamaño al azar entre 100px y 500px */
  height: random(100px, 500px);   /* Tamaño al azar entre 100px y 500px */
  background: indigo;
}

Es importante tener en cuenta que todas las funciones random() que compartan los mismos parámetros se «cachean» y devuelven el mismo valor aleatorio. Es decir, width y height compartiran el mismo valor aleatorio.

Para verlo más claramente, veamos un nuevo ejemplo que sería equivalente al ejemplo anterior. Utilizaremos una variable CSS para guardar el valor y reutilizarlo en otras partes de nuestro código CSS:

.container {
  --size: random(100px, 500px);

  width: var(--size);
  height: var(--size);
  background: indigo;
}

Aunque utilices diferentes random(), si tienen los mismos parámetros compartirán el mismo valor aleatorio. Si esto no es lo que buscas, sigue leyendo en las demás pestañas.

Sin embargo, la función random() permite indicar un primer parámetro opcional (una variable CSS) que se podrá utilizar como identificador único. Este identificador hará que el navegador ignore el cache y genere un valor diferente por cada random() con el mismo identificador único.

En el siguiente ejemplo puedes ver que hemos utilizado dos random(): el primero con el identificador --w para width, y el segundo con el identificador --h para height. Al usar identificadores distintos, generará valores aleatorios diferentes:

.container {
  width: random(--w, 100px, 500px);    /* Independiente del siguiente */
  height: random(--h, 100px, 500px);   /* Independiente del anterior */
  background: indigo;
}

Por lo tanto, este elemento resultará en un elemento rectángulo, que no será un cuadrado (bueno... exceptuando la posibilidad de que los dos números aleatorios coincidan).

Existe la posibilidad de que queramos valores aleatorios independientes por cada «instancia» de elemento HTML. Vamos a explicar esto con un pequeño ejemplo:

<div class="container"></div>
<div class="container"></div>

<style>
.container {
  width: random(per-element, 100px, 500px);
  height: random(per-element, 100px, 500px);
  background: indigo;
}
</style>

En este caso, tenemos dos elementos .container en nuestro HTML. Utilizando random() con el primer parámetro per-element, estaremos indicando al navegador que el valor aleatorio debe ser generado por cada elemento. Por lo tanto, el primer <div> tendrá un valor aleatorio independiente del segundo <div>, que tendrá otro diferente.

Valores limitados por saltos

Podemos restringir la generación de valores aleatorios mediante un parámetro adicional (y opcional) seguido de la palabra clave by. Esto permitirá establecer patrones de saltos, en este ejemplo de 50px en 50px:

.container {
  --size: random(100px, 300px, by 50px);
  --border-size: calc(var(--size) / 4);

  width: var(--size);
  height: var(--size);
  border: var(--border-size) solid black;
  background: indigo;
}

En este caso estamos indicando que nos genere un cuadrado que será de tamaño 100px, 150px, 200px, 250px o 300px.

La función random-item()

Mediante la función random-item() podemos establecer por parámetro una lista de valores y el navegador nos devolverá uno de ellos aleatoriamente.

De la misma forma que vimos anteriormente, podemos utilizar la función random-item() para obtener uno de los valores de forma aleatoria. Si escribimos varias veces la misma función random-item() con los mismos valores por parámetro, se compartirán y usarán el mismo:

.element {
  width: 200px;
  height: 200px;
  background: random-item(indigo, deeppink, tomato);
  border: 5px solid random-item(indigo, deeppink, tomato);
}

Como puedes ver, ambas funciones random-item() tienen los mismos parámetros, por lo que el valor aleatorio que salga en la primera, se utilizará también en la segunda.

Nuevamente, podemos utilizar identificadores únicos para obtener valores aleatorios diferentes también con random-item(). Veamos el ejemplo anterior modificado:

.element {
  width: 200px;
  height: 200px;
  background: random-item(--bg, indigo, deeppink, tomato);
  border: 5px solid random-item(--border, indigo, deeppink, tomato);
}

En este caso, si que se asignarán valores aleatorios independientes en cada función, ya que tienen un identificador diferente, --bg en la primera función y --border en la segunda.

Por último, podemos utilizar la palabra clave per-element para obligar a random-item() a generar un valor aleatorio diferente en cada elemento que renderice el navegador. Veamos un ejemplo donde se ilustrará mejor:

<div class="element"></div>
<div class="element"></div>

<style>
.element {
  width: 200px;
  height: 200px;
  background: random-item(per-element, indigo, deeppink, tomato);
  border: 5px solid random-item(per-element, indigo, deeppink, tomato);
}
</style>

En este caso, el primer <div> tendrá un background aleatorio y un border aleatorio. El segundo <div> también tendrá un background aleatorio y un border aleatorio, ya que no están conectados unos con otro, y se genera un valor aleatorio por cada elemento concreto.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev