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

我已经考虑了一段时间了,所以现在我想了解你的意见,可能的解决方案等等。

我正在寻找一种插件或技术来改变文本的颜色,或者根据它的父母背景图像或颜。

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

另外,如果脚本没有定义背景颜色或-image,然后继续搜索最近的(从父元素到它的父元素......),脚本会注意到它会很棒。。

您怎么看,知道这个想法? 那里有类似的东西吗?脚本的例子吗?

干杯,J。

7个解决方案
147 votes

有趣的资源:

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

这里是W3C算法(也有JSFiddle演示):

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="bg">Text Example</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="bg">Text Example</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="bg">Text Example</div>

Alex Ball answered 2019-08-13T22:50:42Z
41 votes

有关计算颜色对比度的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';
}
cyang answered 2019-08-13T22:51:14Z
15 votes

有趣的问题。 我的直接想法是将背景的颜色反转为文本。 这涉及简单地解析背景并反转其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+')');
jeremyharris answered 2019-08-13T22:51:46Z
4 votes

我发现BackgroundCheck脚本非常有用。

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

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

(资源)

cptstarling answered 2019-08-13T22:52:26Z
4 votes

<header> <h2 contentEditable role='textbox' aria-multiline='true' >Edit me here</h2> </header>可以解决问题:

<header>
  <h2 contentEditable role='textbox' aria-multiline='true' >Edit me here</h2>
</header>
<header>
  <h2 contentEditable role='textbox' aria-multiline='true' >Edit me here</h2>
</header>

增加(2018年3月):以下是一个很好的教程,解释了所有不同类型的模式/实现:[https://css-tricks.com/css-techniques-and-effects-for-knockout-text/]

James Cazzetta answered 2019-08-13T22:53:07Z
3 votes

这是我的尝试:

(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,并且溢出不被隐藏)。 要使这项工作变得更加复杂。

Nathan MacInnes answered 2019-08-13T22:53:56Z
2 votes

如果您使用的是ES6,请将十六进制转换为RGB,然后可以使用:

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))
Luke Robertson answered 2019-08-13T22:54:21Z
translate from https://stackoverflow.com:/questions/11867545/change-text-color-based-on-brightness-of-the-covered-background-area