Como ler o valor do estilo na função CSS
Estou criando vários divs em Javascript inserindo algo assim
'<div style="background-color:' + bgColor + '</div>'
Agora, quero definir o colordo texto automaticamente com base na luminosidade do fundo para preto ou branco.
Vejo 2 opções - todas baseadas em Javascript ou apenas em CSS. Eu prefiro a opção CSS, no entanto, não sei como ler a cor de fundo de uma função CSS, por exemplo
@function set-color($color) { @if (lightness($color) > 40) {
@return #000;
}
@else {
@return #FFF;
}
}
Como posso obter a cor de fundo para fazer algo assim
div { color: set-color(???); }
Que tal mix-blend-mode?
Respostas
Existem várias idéias apresentadas na pergunta sobre como escolher entre preto e branco para a cor do texto, dependendo da cor de fundo.
A maioria foi respondida de uma forma ou de outra nos comentários. Pegando as ideias uma por uma:
Podemos usar o modo mix-blend-blend CSS - não. Não há uma configuração para isso que garanta que o texto aparecerá legível em todos os fundos possíveis.
Podemos usar CSS (o método preferido) - infelizmente não, pois o div que exige que a cor do texto dependa da cor de fundo é criado por JS em tempo de execução.
Podemos usar JS - sim e como o div está sendo criado por JS e tendo sua cor de fundo definida, então ele também pode ter sua cor definida.
A string JS é como fornecida na pergunta com a adição de uma configuração para a cor:
'<div style = "background-color:' + bgColor + '; color:' + textBlackOrWhite (bgColor) + ';"'
Aqui está um trecho que define a função. O snippet também permite que você escolha uma cor de fundo e então define uma cor que (aproximadamente) depende do 'brilho' do fundo. Consulte as perguntas do SO mencionadas aqui para uma discussão mais aprofundada, pois a percepção humana das cores é um tópico difícil.
//from https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
function textBlackOrWhite(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, function(m, r, g, b) { return r + r + g + g + b + b; }); let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);//also checks we have a well-formed hex number
//from https://stackoverflow.com/questions/596216 the answer by @FranciPenov which gives an approximation: (R+R+G+G+G+B)/6
let itsbright = function () { return ((2*parseInt(result[1], 16) + 3*parseInt(result[2], 16) + parseInt(result[3], 16))/6)>127; }
return result ? (itsbright()) ? '#000000' : '#ffffff' : '#000000';//falls back onto black if bgColor was not a well-formed 3 or 6 digit hex color
}
<div id="div" style="font-family: monospace; box-sizing: border-box; margin: 0; padding: 40px 0; width: 100px; height: 100px; border-style: solid; border-radius: 50%; background-color: black; color: white;text-align:center;">#ffffff</div>
Click to choose background color: <input id="input" placeholder='#00000' type='color' value='#000000'/>
<button onclick="let d = document.getElementById('div'); let i = document.getElementById('input'); d.innerHTML = i.value; d.style.backgroundColor = i.value; d.style.color = textBlackOrWhite(i.value);">Submit</button>
Desejo definir a cor do texto automaticamente com base na luminosidade do fundo para preto ou branco.
Eu reconheço que esta é uma abordagem diferente do que você está pedindo, mas uma abordagem somente CSS para ter texto legível universalmente, independentemente de background-colorter whitetexto com blackcontorno (ou vice-versa).
Você pode usar 4 sombras de texto para o contorno:
text-shadow: 1px 1px rgb(0, 0, 0), -1px 1px rgb(0, 0, 0), -1px -1px rgb(0, 0, 0), 1px -1px rgb(0, 0, 0);
Exemplo de Trabalho
const divs = [...document.getElementsByTagName('div')];
for (div of divs) {
let redValue = Math.floor(Math.random() * 255);
let greenValue = Math.floor(Math.random() * 255);
let blueValue = Math.floor(Math.random() * 255);
div.style.backgroundColor = `rgb(${redValue}, ${greenValue}, ${blueValue})`;
}
div {
float: left;
width: 180px;
height: 40px;
margin: 0 6px 6px 0;
line-height: 40px;
color: rgb(255, 255, 255);
font-size: 32px;
text-align: center;
text-shadow: 1px 1px rgb(0, 0, 0), -1px 1px rgb(0, 0, 0), -1px -1px rgb(0, 0, 0), 1px -1px rgb(0, 0, 0);
background-color: yellow;
}
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>