> Manuales > Taller de Javascript

Cómo hacer que una página cambie de color cada vez que se visita, colocando un color aleatorio y con el texto que contraste para que se pueda leer bien.

Página que cambia aleatoriamente el color de fondo

En este artículo vamos a mostrar cómo podríamos crear una página que tiene con color de fondo aleatorio, de modo que, cada vez que se visite o se recargue, se muestre con un fondo distinto. Para ello usaremos una función que crea colores aleatorios pero también aprenderemos a resolver un problema que podemos encontrar con el color del texto.

Este ejemplo lo vamos a ver además realizado de dos modos, un más antiguo en el que se modificaba la etiqueta body haciendo uso del atributo bgcolor (color de fondo) y text (color del texto), que es actualmente una práctica poco recomendada. Además lo hemos actualizado para ajustar el color del fondo y el texto mediante CSS, que sería la práctica recomendable ahora mismo.

Entender el problema del color de texto que contraste

Hay que darse cuenta que, si el color de fondo es aleatorio, a veces saldrá más oscuro y a veces más claro. Para que se lea bien el texto, su color tiene que contrastar lo suficiente con el color de fondo, por eso calcularemos la oscuridad o claridad del fondo para fijar el color del texto.

De este modo, para asegurarnos que el texto se pueda leer correctamente, haremos que el texto de la página sea o blanco o negro, dependiendo de la gama del color de fondo: si es oscuro, el texto de la página será blanco y si el fondo es claro, el texto se verá en negro.

Cómo obtener un color aleatorio

En un artículo anterior del taller de Javascript ya explicamos una manera de conseguir un color aleatorio en Javascript.

Aunque en el mencionado artículo ya estaba la función Javascript para obtener un color aleatorio, la transcribimos aquí, pues hemos hecho un par de cambios minúsculos al código:

function dameNumeroAleatorio(superior, inferior) {
  let numPosibilidades = (superior + 1) - inferior;
  let aleat = Math.random() * numPosibilidades;
  aleat = Math.floor(aleat);
  aleat = (inferior + aleat);
  return aleat
}

function dameColorAleatorio() {
  let hexadecimal = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
  let color_aleat = "#"
  let inferior = 0;
  let superior = hexadecimal.length - 1;
  for (i = 0; i < 6; i++) {
    color_aleat += hexadecimal[dameNumeroAleatorio(superior, inferior)];
  }
  return color_aleat
}

En el Taller de Javascript también tienes explicaciones sobre cómo conseguir números aleatorios entre un mínimo y un máximo con Javascript.

Cómo calcular si un color es claro u oscuro

Como habíamos dicho, otro de los problemas que nos íbamos a enfrentar es calcular si el color es más claro o más oscuro que un umbral dado.

La manera de conocer la oscuridad o claridad de un color con aleatorio generado por Javascript seguramente se pueda hacer de diversas maneras, pero nosotros vamos a optar por un sencillo mecanismo que seguramente cualquier persona podrá comprender. Para calcular la oscuridad (o claridad) de un color vamos a examinar las componentes en formato RGB (partiendo de una notación hexadecimal de nuestro color aleatorio).

Lo realizaremos partiendo de este hecho: a mayores valores de RGB, el color resultante será mas claro. Por contra, si los valores de RGB son más bajos, el color será más oscuro.

Los valores de R, G y B, por separado pueden ir, en decimal, desde 0 a 255. Diremos que es claro cuando sea mayor que 255 / 2 y que es oscuro cuando sea menor de 255 / 2.

Vamos a suponer un umbral a partir del cual el color lo consideramos más oscuro o más claro. Digamos que si sumamos por separado los valores rojo, verde y azul y nos dan más de la mitad de ((255 + 255 +255) / 2), es que el color es claro. Si está por debajo de ese umbral, el color es oscuro.

Así pues, nuestro algoritmo se basará en varios pasos:

Todo esto se traduce en una función Javascript que vamos a ver enseguida. La función recibirá como parámetro un color en un string con el formato #RRGGBB. Devolverá como respuesta el RGB del color blanco o el color negro. Si el color de entrada era oscuro devolverá "#ffffff" y si era más bien claro devolverá "#000000".

function calcularColorDelTexto(color) {
  // voy a extraer las tres partes del color
  let rojo = color.substring(1, 3);
  let verde = color.substring(3, 5);
  let azul = color.substring(5, 7);

  // voy a convertir a enteros los string, que tengo en hexadecimal
  let introjo = parseInt(rojo, 16);
  let intverde = parseInt(verde, 16);
  let intazul = parseInt(azul, 16);

  // ahora sumo los valores
  let oscuridad = introjo + intverde + intazul

  // Defino el umbral entre oscuro y claro
  let umbral = (255 + 255 + 255) / 2
  // si el valor oscuridad es menor que ((255 + 255 + 255) / 2) es que es un color más oscuro
  // si es oscuro, el color del texto será blanco
  if (oscuridad < umbral)
    return "#ffffff";
  else
    return "#000000";
}

Con esto ya tenemos todo lo necesario para poder manipular la página y colocar el color aleatorio de fondo y el color del texto blanco o negro, con el contraste adecuado según el fondo. Sin embargo, en esta parte podemos proceder de diversas maneras y todas pueden tener sus ventajas e inconveientes. Atendiendo a ellas vamos a ver dos alternativas, una que es la original que se presentó en la primera publicación de este artículo y otra más moderna que a día de hoy es a nuestro juicio más adecuada.

Las dos posibilidades en síntesis son estas:

La primera alternativa es preferible, básicamente porque el color de fondo y el color del texto son decisiones de diseño y deberían delegarse en el CSS. Pero lo cierto es que en este ejercicio estamos trabajando con Javascript así que en cierto modo no estamos aplicando ni una ni otra posibilidad. No obstante preferimos desde un punto de vista más conceptual manipular el CSS con Javascript que manipular el HTML.

Manipulando dinámicamente los estilos CSS del body

Para cambiar los colores de fondo y del texto de cualquier elemento del DOM usamos la propiedad style y luego las propiedades de CSS que ya seguramente conocemos.

let colorFondo = dameColorAleatorio();
let colorTexto = calcularColorDelTexto(colorFondo);

document.body.style.backgroundColor =  colorFondo;
document.body.style.color = colorTexto;

El único detalle es que queremos que este código se ejecute lo más rápido posible. Si esperamos a ejecutarlo cuando la página termine de cargar podría ocurrir que el color solo se modifique más tarde que la página ya estaba renderizada, haciendo un feo efecto como de parpadeo.

Por ese motivo, este código lo vamos a colocar justo después de haber abierto el tag <body> de la página. No es lo que más se aconsejaría, pero en este caso concreto es la mejor opción.

El código completo lo podemos ver aquí.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Cómo hacer un color aleatorio para el fondo y el texto</title>
</head>
<body>

  <script>
    function dameNumeroAleatorio(superior, inferior) {
      let numPosibilidades = (superior + 1) - inferior;
      let aleat = Math.random() * numPosibilidades;
      aleat = Math.floor(aleat);
      aleat = (inferior + aleat);
      return aleat
    }

    function dameColorAleatorio() {
      let hexadecimal = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
      let color_aleat = "#"
      let inferior = 0;
      let superior = hexadecimal.length - 1;
      for (i = 0; i < 6; i++) {
        color_aleat += hexadecimal[dameNumeroAleatorio(superior, inferior)];
      }
      return color_aleat
    }

    function calcularColorDelTexto(color) {
      // voy a extraer las tres partes del color
      let rojo = color.substring(1, 3);
      let verde = color.substring(3, 5);
      let azul = color.substring(5, 7);

      // voy a convertir a enteros los string, que tengo en hexadecimal
      let introjo = parseInt(rojo, 16);
      let intverde = parseInt(verde, 16);
      let intazul = parseInt(azul, 16);

      // ahora sumo los valores
      let oscuridad = introjo + intverde + intazul

      // Defino el umbral entre oscuro y claro
      let umbral = (255 + 255 + 255) / 2
      // si el valor oscuridad es menor que ((255 + 255 + 255) / 2) es que es un color más oscuro
      // si es oscuro, el color del texto será blanco
      if (oscuridad < umbral)
        return "#ffffff";
      else
        return "#000000";
    }

    let colorFondo = dameColorAleatorio();
    let colorTexto = calcularColorDelTexto(colorFondo);

    document.body.style.backgroundColor =  colorFondo;
    document.body.style.color = colorTexto;
  </script>

  <h1>Ejemplo de página con el color aleatorio</h1>
  <p>El color del fondo va a cambiar con cada recarga. Además el color del texto podrá ser blanco o negro, para contratar con el color aleatorio que haya salido.</p>
</body>
</html>

Cómo cambiar el color de fondo basado en atributos del body

Ahora vamos a ver otra alternativa que, como decimos, era la que se había publicado al escribir originalmente el artículo. Tiene dos problemas que queremos comentar antes que nada.

Para actualizar el color de fondo y de texto de una página web se podría hacer con estas líneas de código:

document.fgColor = colorTexto 
document.bgColor = colorFondo

Pero esto da un problema en algunos navegadores, al cambiar el color del texto, que no se puede hacer si previamente se ha escrito algo en la página.

Adicionalmente las propiedades fgColor y bgColor están declaradas como obsoletas, aunque puedan funcionar todavía por retrocompatibilidad.

Entonces, vamos a marcar el color del fondo y del texto utilizando los conocidos atributos bgcolor y text de la etiqueta <body>.

Escribiremos el <body> mediante javascript, colocando los valores de color aleatorio y color del texto que extraemos de las variables que los contienen.

document.write('<body bgcolor="' + colorin + '" text="' + colortexto + '">');

Eso es todo. Ya tenemos la página con el color de fondo aleatorio y el color del texto con suficiente contraste.

Podemos ver su código fuente para obtener script del ejemplo completo.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Cómo hacer un color aleatorio para el fondo y el texto</title>
</head>
  <script>
    function dameNumeroAleatorio(superior, inferior) {
      let numPosibilidades = (superior + 1) - inferior;
      let aleat = Math.random() * numPosibilidades;
      aleat = Math.floor(aleat);
      aleat = (inferior + aleat);
      return aleat
    }

    function dameColorAleatorio() {
      let hexadecimal = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
      let color_aleat = "#"
      let inferior = 0;
      let superior = hexadecimal.length - 1;
      for (i = 0; i < 6; i++) {
        color_aleat += hexadecimal[dameNumeroAleatorio(superior, inferior)];
      }
      return color_aleat
    }

    function calcularColorDelTexto(color) {
      // voy a extraer las tres partes del color
      let rojo = color.substring(1, 3);
      let verde = color.substring(3, 5);
      let azul = color.substring(5, 7);

      // voy a convertir a enteros los string, que tengo en hexadecimal
      let introjo = parseInt(rojo, 16);
      let intverde = parseInt(verde, 16);
      let intazul = parseInt(azul, 16);

      // ahora sumo los valores
      let oscuridad = introjo + intverde + intazul

      // Defino el umbral entre oscuro y claro
      let umbral = (255 + 255 + 255) / 2
      // si el valor oscuridad es menor que ((255 + 255 + 255) / 2) es que es un color más oscuro
      // si es oscuro, el color del texto será blanco
      if (oscuridad < umbral)
        return "#ffffff";
      else
        return "#000000";
    }

      let colorFondo = dameColorAleatorio();
      let colorTexto = calcularColorDelTexto(colorFondo);

      document.write(`<body bgcolor="${colorFondo}" text="${colorTexto}">`);
  </script>


  <h1>Ejemplo de página con el color aleatorio</h1>
  <p>En este ejemplo usamos document.write() que no es muy aconsejable. También usamos los atributos de la etiqueta body bgcolor y text que ya tampoco se aconsejan usar.</p>
  <p>El color del fondo va a cambiar con cada recarga. Además el color del texto podrá ser blanco o negro, para contratar con el color aleatorio que haya salido.</p>
</body>
</html>

Como puedes observar, el bloque principal de este ejemplo es igual que el anterior. Solamente cambia el modo en el que se asigna el color de fordo a la página. Espero que te haya servido para entender otros modos de proceder.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual