Variables CSS + calc() + rgb() = Aplicación de colores de alto contraste | Programar Plus

Como sabrá, las actualizaciones y adiciones recientes a CSS son extremadamente poderosas. Desde Flexbox hasta Grid y, lo que nos preocupa aquí, las propiedades personalizadas (también conocidas como variables CSS), todo lo cual hace que los diseños e interfaces robustos y dinámicos sean más fáciles que nunca al tiempo que abren muchas otras posibilidades con las que solíamos soñar.

El otro día, estaba pensando que debe haber una manera de usar Propiedades personalizadas para colorear el fondo de un elemento mientras mantiene un contraste con el color de primer plano que sea lo suficientemente alto (usando blanco o negro) para pasar los estándares de accesibilidad WCAG AA.

Es asombrosamente eficiente hacer esto en JavaScript con unas pocas líneas de código:

var rgb = [255, 0, 0];

function setForegroundColor() {
  var sum = Math.round(((parseInt(rgb[0]) * 299) + (parseInt(rgb[1]) * 587) + (parseInt(rgb[2]) * 114)) / 1000);
  return (sum > 128) ? 'black' : 'white';
}

Esto toma los valores rojo, verde y azul (RGB) del color de fondo de un elemento, los multiplica por algunos números especiales (299, 587 y 144, respectivamente), los suma y luego divide el total por 1000. Cuando esa suma sea superior a 128, devolverá negro; de lo contrario, obtendremos blanco. No está mal.

El único problema es que, cuando se trata de recrear esto en CSS, no tenemos acceso a un nativo if declaración para evaluar la suma. Entonces, ¿cómo podemos replicar esto en CSS sin uno?

Afortunadamente, al igual que HTML, CSS puede ser muy indulgente. Si pasamos un valor superior a 255 a la función RGB, se limitará a 255. Lo mismo ocurre con los números inferiores a 0. Incluso los números enteros negativos se limitarán a 0. Entonces, en lugar de probar si nuestra suma es mayor o menor que 128, restamos 128 de nuestra suma, lo que nos da un número entero positivo o negativo. Luego, si lo multiplicamos por un valor negativo grande (por ejemplo, -1000), terminamos con valores positivos o negativos muy grandes que luego podemos pasar a la función RGB. Como dije antes, esto se limitará a los valores deseados del navegador.

Aquí hay un ejemplo usando variables CSS:

:root {
  --red: 28;
  --green: 150;
  --blue: 130;

  --accessible-color: calc(
    (
      (
        (
          (var(--red) * 299) +
          (var(--green) * 587) +
          (var(--blue) * 114)
        ) / 1000
      ) - 128
    ) * -1000
  );
}

.button {
  color:
    rgb(
      var(--accessible-color),
      var(--accessible-color),
      var(--accessible-color)
    );
  background-color:
    rgb(
      var(--red),
      var(--green),
      var(--blue)
    );
}

Si mis cálculos son correctos (y es muy posible que no lo sea) obtenemos un total de 16 758, que es mucho mayor que 255. Pase este total a la rgb() función para los tres valores, y el navegador establecerá el color del texto en blanco.

Agregue algunos controles deslizantes de rango para ajustar el color valores, y ahí lo tiene: un elemento de interfaz de usuario dinámico que puede cambiar el color del texto en función de su background-color mientras mantiene una calificación aprobatoria con WCAG AA.

ver la pluma
Botón CSS solo accesible por Josh Bader (@joshbader)
en CodePen.

Poner este concepto en práctica

A continuación se muestra un lápiz que muestra cómo se puede utilizar esta técnica para crear un tema en una interfaz de usuario. He duplicado y movido el --accessible-color variable en las reglas CSS específicas que lo requieren, y para ayudar a garantizar que los fondos permanezcan accesibles en función de sus primeros planos, he multiplicado el --accessible-color variable por -1 en varios lugares. Los colores se pueden cambiar usando los controles ubicados en la parte inferior derecha. Haga clic en el icono de rueda dentada/engranaje para acceder a ellos.

ver la pluma
Interfaz de usuario accesible variable CSS por Josh Bader (@joshbader)
en CodePen.

Hay otras formas de hacer esto

Hace un tiempo, Facundo Corradini explicó cómo hacer algo muy similar en este post. Él usa un cálculo ligeramente diferente en combinación con el hsl función. También entra en detalles sobre algunos de los problemas que estaba teniendo mientras se le ocurría el concepto:

Algunos tonos se vuelven realmente problemáticos (particularmente amarillos y cian), ya que se muestran mucho más brillantes que otros (por ejemplo, rojos y azules) a pesar de tener el mismo valor de luminosidad. En consecuencia, algunos colores se tratan como oscuros y se les asigna un texto blanco a pesar de ser extremadamente brillantes.

¿Qué está pasando en el nombre de CSS?

Continúa mencionando que Edge no estaba limitando sus grandes números, y durante mi prueba, noté que a veces funcionaba y otras veces no. Si alguien puede precisar por qué esto podría ser, siéntase libre de compartir en los comentarios.

Además, Ana Tudor explica cómo utilizar filter + mix-blend-mode puede ayudar a contrastar el texto con fondos más complejos. Y, cuando digo complejo, quiero decir complejo. Incluso va tan lejos como para demostrar cómo el color del texto puede cambiar a medida que cambian las piezas del color de fondo, ¡bastante increíble!

Además, Robin Rendle explica cómo usar mix-blend-mode junto con pseudo elementos para invertir automáticamente los colores del texto en función de su background-color.

Entonces, cuente esto como otro enfoque más para incluir en la mezcla. Es increíblemente increíble que las propiedades personalizadas nos abran este tipo de posibilidades y nos permitan resolver el mismo problema de varias maneras.

(Visited 7 times, 1 visits today)