Pregunta

En una de las páginas en las que estamos trabajando actualmente, los usuarios pueden cambiar el fondo del texto que se muestra.

Nos gustaría modificar automáticamente el color de primer plano para mantener un contraste razonable del texto.

También preferiríamos que la gama de colores sea discrecional. Por ejemplo, si el fondo cambia de blanco a negro en incrementos de 255, no queremos ver 255 sombras de color de primer plano. En este escenario, quizás de 2 a 4, solo para mantener un contraste razonable .

¿Algún especialista en UI / diseño / color / pintores para sacar la fórmula?

¿Fue útil?

Solución

En términos de legibilidad pura, desea utilizar texto en blanco y negro en cualquier fondo que sea. Por lo tanto, convierta RGB a HSV y compruebe si V es & Lt; 0.5. Si es así, blanco, si no, negro.

Pruebe eso primero y vea si le resulta atractivo.

Si no lo hace, entonces probablemente desee que el blanco y el negro no sean tan marcados cuando su fondo sea demasiado brillante o demasiado oscuro. Para atenuar esto, mantenga el mismo tono y saturación, y use estos valores para el brillo:

background V  foreground V
0.0-0.25      0.75
0.25-0.5      1.0
0.5-0.75      0.0
0.75-1.0      0.25

En un color medio, aún verá texto en blanco o negro que será muy fácil de leer. En un color oscuro o claro, verá el mismo texto de color pero al menos a 3/4 de distancia en términos de brillo y, por lo tanto, aún legible. Espero que se vea bien :)

Otros consejos

Basar tu decisión en blanco y negro de luma me funciona bastante bien. Luma es una suma ponderada de los valores R, G y B, ajustada para la percepción humana del brillo relativo, aparentemente común en aplicaciones de video. La definición oficial de luma ha cambiado con el tiempo, con diferentes ponderaciones; ver aquí: http://en.wikipedia.org/wiki/Luma_(video). Obtuve los mejores resultados usando la Rec. Versión 709, como en el siguiente código. Un umbral blanco y negro de quizás 165 parece bueno.

function contrastingColor(color)
{
    return (luma(color) >= 165) ? '000' : 'fff';
}
function luma(color) // color can be a hx string or an array of RGB values 0-255
{
    var rgb = (typeof color === 'string') ? hexToRGBArray(color) : color;
    return (0.2126 * rgb[0]) + (0.7152 * rgb[1]) + (0.0722 * rgb[2]); // SMPTE C, Rec. 709 weightings
}
function hexToRGBArray(color)
{
    if (color.length === 3)
        color = color.charAt(0) + color.charAt(0) + color.charAt(1) + color.charAt(1) + color.charAt(2) + color.charAt(2);
    else if (color.length !== 6)
        throw('Invalid hex color: ' + color);
    var rgb = [];
    for (var i = 0; i <= 2; i++)
        rgb[i] = parseInt(color.substr(i * 2, 2), 16);
    return rgb;
}

Pruebe este ejemplo , que solo lo establece en blanco o negro según el promedio de los valores r, g y b. ¡También es bueno para probar! Sustituya un algoritmo mejor si encuentra casos que no funcionan muy bien.

<html> 
<head> 
<script> 
function rgbstringToTriplet(rgbstring)
{
    var commadelim = rgbstring.substring(4,rgbstring.length-1);
var strings = commadelim.split(",");
var numeric = [];
for(var i=0; i<3; i++) { numeric[i] = parseInt(strings[i]); }
return numeric;
}

function adjustColour(someelement)
{
   var rgbstring = someelement.style.backgroundColor;
   var triplet = rgbstringToTriplet(rgbstring);
   var newtriplet = [];
   // black or white:
   var total = 0; for (var i=0; i<triplet.length; i++) { total += triplet[i]; } 
   if(total > (3*256/2)) {
     newtriplet = [0,0,0];
   } else {
 newtriplet = [255,255,255];
   }
   var newstring = "rgb("+newtriplet.join(",")+")";
   someelement.style.color = newstring;
   return true;
}

function randomiseBackground(someelement)
{
 var vals = [];
 for(var i=0; i<3; i++) { vals[i]=Math.floor(Math.random()*256+1); }
 someelement.style.backgroundColor="rgb("+vals.join(",")+")";
 return true;
}
</script> 
</head> 
<body onload="adjustColour(document.getElementById('mypara'));"> 
<p id="mypara" style="background-color:#2287ea">Some text</p> 
<form> 
    <input type=button onclick="var elem=document.getElementById('mypara'); randomiseBackground(elem); adjustColour(elem);" value="randomise background" /> 
</form> 
</body> 
</html>

Probablemente desee cambiar el tono, pero no la saturación o el valor.

Entonces, convierta su valor RGB en HSV, agregue 180 grados a H (módulo 360 grados por supuesto) y vuelva a convertir a RGB.

Los foros de conversión están aquí .

Es un poco complicado implementarlo debido a la forma en que javascript trata los valores decimales. Para este propósito, he encontrado que es mucho mejor dejar que el fondo cambie cualquier color, pero el texto simplemente cambia entre blanco y negro. Si usa colores contrastantes, muchas combinaciones serán realmente difíciles de soportar. También tenga en cuenta que algunas personas son daltónicas, por lo que no es una muy buena idea desde la perspectiva de accesibilidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top