我已经考虑了一段时间了,所以现在我想知道你的意见,可能的解决方案等等。
我正在寻找一种插件或技术来改变文本的颜色或在预定义的图像/图标之间切换,具体取决于它的父级背景图像或颜色的覆盖像素的平均亮度。
如果背景的覆盖区域相当暗,请将文本设为白色或切换图标。
此外,如果脚本没有定义背景颜色或-image然后继续搜索最接近的(从父元素到它的父元素......)脚本会发现它会很棒。
你怎么看,知道这个想法?那里有类似的东西吗?脚本的实例?
干杯,J。
答案 0 :(得分:148)
有趣的资源:
这是W3C算法(带JSFiddle demo too):
var rgb = [255, 0, 0];
// randomly change to showcase updates
setInterval(setContrast, 1000);
function setContrast() {
// randomly update
rgb[0] = Math.round(Math.random() * 255);
rgb[1] = Math.round(Math.random() * 255);
rgb[2] = Math.round(Math.random() * 255);
// http://www.w3.org/TR/AERT#color-contrast
var o = Math.round(((parseInt(rgb[0]) * 299) +
(parseInt(rgb[1]) * 587) +
(parseInt(rgb[2]) * 114)) / 1000);
var fore = (o > 125) ? 'black' : 'white';
var back = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
$('#bg').css('color', fore);
$('#bg').css('background-color', back);
}
#bg {
width: 200px;
height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bg">Text Example</div>
答案 1 :(得分:43)
关于Calculating Color Contrast的24种方法的文章可能会让您感兴趣。忽略第一组函数,因为它们是错误的,但YIQ公式将帮助您确定是否使用浅色或深色前景色。
获得元素(或祖先)的背景颜色后,您可以使用文章中的此功能来确定合适的前景色:
function getContrastYIQ(hexcolor){
var r = parseInt(hexcolor.substr(0,2),16);
var g = parseInt(hexcolor.substr(2,2),16);
var b = parseInt(hexcolor.substr(4,2),16);
var yiq = ((r*299)+(g*587)+(b*114))/1000;
return (yiq >= 128) ? 'black' : 'white';
}
答案 2 :(得分:15)
有趣的问题。我的直接想法是将背景的颜色反转为文本。这包括简单地解析背景并反转其RGB值。
像这样:http://jsfiddle.net/2VTnZ/2/
var rgb = $('#test').css('backgroundColor');
var colors = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
var brightness = 1;
var r = colors[1];
var g = colors[2];
var b = colors[3];
var ir = Math.floor((255-r)*brightness);
var ig = Math.floor((255-g)*brightness);
var ib = Math.floor((255-b)*brightness);
$('#test').css('color', 'rgb('+ir+','+ig+','+ib+')');
答案 3 :(得分:4)
我发现BackgroundCheck脚本非常有用。
它会检测背景的整体亮度(无论是背景图像还是颜色),并根据亮度将类应用于指定的文本元素(background--light
或background--dark
)背景。
它可以应用于静止和移动元素。
(Source)
答案 4 :(得分:4)
music_type := ...
fmt.Println(music_type) // Rock
可以解决问题:
mix-blend-mode
&#13;
header {
overflow: hidden;
height: 100vh;
background: url(https://www.w3schools.com/html/pic_mountain.jpg) 50%/cover;
}
h2 {
color: white;
font: 900 35vmin/50vh arial;
text-align: center;
mix-blend-mode: difference;
filter: drop-shadow(0.05em 0.05em orange);
}
&#13;
加法(2018年3月): 下面是一个很好的教程,解释了所有不同类型的模式/实现:https://css-tricks.com/css-techniques-and-effects-for-knockout-text/
答案 5 :(得分:3)
这是我的尝试:
(function ($) {
$.fn.contrastingText = function () {
var el = this,
transparent;
transparent = function (c) {
var m = c.match(/[0-9]+/g);
if (m !== null) {
return !!m[3];
}
else return false;
};
while (transparent(el.css('background-color'))) {
el = el.parent();
}
parts = el.css('background-color').match(/[0-9]+/g);
this.lightBackground = !!Math.round(
(
parseInt(parts[0], 10) + // red
parseInt(parts[1], 10) + // green
parseInt(parts[2], 10) // blue
) / 765 // 255 * 3, so that we avg, then normalise to 1
);
if (this.lightBackground) {
this.css('color', 'black');
} else {
this.css('color', 'white');
}
return this;
};
}(jQuery));
然后使用它:
var t = $('#my-el');
t.contrastingText();
这将立即生效,使文本适当地为黑色或白色。要做图标:
if (t.lightBackground) {
iconSuffix = 'black';
} else {
iconSuffix = 'white';
}
然后每个图标看起来都像'save' + iconSuffix + '.jpg'
。
请注意,这在任何容器溢出其父级时都不起作用(例如,如果CSS高度为0,并且未隐藏溢出)。要使这项工作变得更加复杂。
答案 6 :(得分:2)
如果您使用的是ES6,请将十六进制转换为RBG,然后可以使用:
const hexToRgb = hex => {
// turn hex val to RGB
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
}
: null
}
// calc to work out if it will match on black or white better
const setContrast = rgb =>
(rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000 > 125 ? 'black' : 'white'
const getCorrectColor = setContrast(hexToRgb(#ffffff))
答案 7 :(得分:1)
通过结合答案[@ alex-ball,@jeremyharris],我发现这是最适合我的方法:
$('.elzahaby-bg').each(function () {
var rgb = $(this).css('backgroundColor');
var colors = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
var r = colors[1];
var g = colors[2];
var b = colors[3];
var o = Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) /1000);
if(o > 125) {
$(this).css('color', 'black');
}else{
$(this).css('color', 'white');
}
});
*{
padding: 9px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class='elzahaby-bg' style='background-color:#000'>color is white</div>
<div class='elzahaby-bg' style='background-color:#fff'>color is black</div>
<div class='elzahaby-bg' style='background-color:yellow'>color is black</div>
<div class='elzahaby-bg' style='background-color:red'>color is white</div>