根据覆盖的背景区域的亮度更改文字颜色?

我已经想了一段时间了,所以现在我想知道你的意见,可能的解决scheme,等等。

我正在寻找一种插件或技术来改变文本的颜色,或者根据其父​​母的背景图像或颜色的覆盖像素的平均亮度,在预定义的图像/图标之间切换。

如果背景的覆盖区域比较黑暗,请将文本设为白色或切换图标。

此外,如果脚本会注意到,如果父级没有定义背景颜色或图像,然后继续search最接近的(从父元素到它的父元素..),那就太好了。

你怎么看,知道这个主意? 那里有类似的东西吗? 脚本的例子吗?

干杯,J

有趣的资源:

  • W3C – 确保前景色和背景色组合提供足够的对比度
  • 计算颜色的感知亮度

这里是W3Calgorithm(也有JSFiddle演示 ):

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> 

关于计算颜色对比度的 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'; } 

有趣的问题。 我的直接想法是把背景的颜色翻转为文字。 这涉及简单地parsing背景并反转其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+')'); 

我发现BackgroundCheck脚本非常有用。

它检测背景的整体亮度(无论是背景图像还是颜色),并根据背景的亮度将类应用于指定的文本元素( background--lightbackground--dark )。

它可以应用于静止和移动的元素。

( 来源 )

这是我的尝试:

 (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,并且未隐藏溢出),这将不起作用。 要做到这一点将会复杂得多。

mix-blend-mode的诀窍是:

 header { overflow: hidden; height: 100vh; background: url(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); } 
 <header> <h2 contentEditable role='textbox' aria-multiline='true' >Edit me here</h2> </header> 

如果您使用的是ES6,则将hex转换为RBG,然后可以使用这个:

 const hexToRgb = hex => { // turn hex val to RGB const result = /^#?([af\d]{2})([af\d]{2})([af\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))