Paletas accesibles: calcular contraste WCAG desde colores HEX con JavaScript

Una combinación de colores puede ser atractiva y, al mismo tiempo, difícil de leer. Si diseñamos una app que crea paletas, la vista previa debería ayudarnos a evaluar el contraste, no solo la armonía cromática.

El problema y el alcance del ejemplo

La ficha de Color Palette Hub: Paletas resume su función así: «Crea paletas cromáticas, combina tonos y edita imágenes en una sola app.» Color Palette Hub reúne herramientas de selección cromática y espacios de color. Este tutorial se concentra en la luminancia relativa sRGB y el contraste como una comprobación mínima de accesibilidad. No es una descripción de su algoritmo interno.

Cómo reproducir la idea

Abre la consola de cualquier navegador moderno o utiliza Node.js. Copia el código sin dependencias.

function luminance(hex) { const raw = hex.replace(/^#/, ''); if (!/^[0-9a-fA-F]{6}$/.test(raw)) throw new Error('HEX de 6 dígitos'); const rgb = [0, 2, 4].map(i => parseInt(raw.slice(i, i + 2), 16) / 255); const linear = rgb.map(v => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4); return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2]; } function contrast(foreground, background) { const a = luminance(foreground), b = luminance(background); return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05); } console.log('Negro/blanco:', contrast('#000000', '#FFFFFF').toFixed(2)); console.log('Gris/blanco:', contrast('#777777', '#FFFFFF').toFixed(2)); 

Qué demuestra el código

La función transforma canales sRGB a luz lineal antes de calcular luminancia. El resultado del cociente va de 1:1 a 21:1. Para texto normal, el criterio WCAG AA suele exigir al menos 4.5:1, con excepciones y requisitos distintos según el tipo de contenido.

Pruebas recomendadas

Primero verifica que negro sobre blanco produce 21.00. Cambia el color de texto entre #777777 y #333333 para observar cómo varía el contraste. Después prueba una de tus propias paletas.

Límites que conviene reconocer

La comprobación cubre colores sRGB opacos y no evalúa fondos complejos, gradientes, transparencias, tipo de letra ni todo el conjunto de WCAG. Tampoco reemplaza pruebas con usuarios ni la validación de controles e iconos.

Qué aprendemos

Una paleta útil debe considerar el contexto de uso del color. El contraste medido es una señal objetiva, no una garantía absoluta de buena experiencia.

Contexto y enlaces del autor

El tema se relaciona con las funciones declaradas públicamente de Color Palette Hub: Paletas, una aplicación Android de AppInitDev. El código anterior es un ejemplo independiente: no se ha inspeccionado el repositorio privado ni se afirma que sea la implementación interna de la app. La referencia aparece al final para ofrecer contexto, no como requisito para completar el tutorial.

Image APPS

Referencia técnica

W3C: Understanding Contrast (Minimum)