如何根据背景颜色决定白色或黑色的字体颜色?

我想显示一些像这个例子的图像 替代文字

填充颜​​色由数据库中的字段决定,颜色以hex表示(例如:ClassX – > Color:#66FFFF)。 现在,我想显示填充所选颜色上方的数据(如上图),但是我需要知道颜色是黑暗还是浅色,所以我知道这些单词应该是白色还是黑色。 有没有办法? TKS

build立在我对类似问题的回答上 。

您需要将hex代码拆分为三块,以获得单独的红色,绿色和蓝色强度。 代码的每两位数字表示hex(基数为16)表示法的值。 我不会详细介绍这里的转换,它们很容易查找。

一旦获得了各种颜色的强度,就可以确定颜色的整体强度并select相应的文字。

if (red*0.299 + green*0.587 + blue*0.114) > 186 use #000000 else use #ffffff 

编辑:上面是简单,工作相当好,似乎有很好的接受在这里在StackOverflow。 但是,下面的评论之一显示,在某些情况下,可能导致不遵守W3C指南。 因此,我推导出一种经过修改的forms,总是根据指南select最高的对比度。

W3C推荐的对比度公式为(L1 + 0.05) / (L2 + 0.05) ,其中L1是最亮颜色的亮度, L2是0.0-1.0范围内最暗的亮度。 黑色的亮度是0.0,白色是1.0,所以代替这些值可以确定具有最高对比度的亮度。 如果黑色的对比度大于白色的对比度,则使用黑色,否则使用白色。 鉴于你testing的颜色的亮度Ltesting变成:

 if (L + 0.05) / (0.0 + 0.05) > (1.0 + 0.05) / (L + 0.05) use #000000 else use #ffffff 

这简化了代数:

 if L > sqrt(1.05 * 0.05) - 0.05 

或大约:

 if L > 0.179 use #000000 else use #ffffff 

唯一剩下的就是计算L 指南中也给出了这个公式,它看起来像是从sRGB到线性RGB的转换,接着是ITU-R关于亮度的BT.709build议 。

 for each c in r,g,b: c = c / 255.0 if c <= 0.03928 then c = c/12.92 else c = ((c+0.055)/1.055) ^ 2.4 L = 0.2126 * r + 0.7152 * g + 0.0722 * b 

这个(JavaScript代码)怎么样?

 /** * Get color (black/white) depending on bgColor so it would be clearly seen. * @param bgColor * @returns {string} */ getColorByBgColor(bgColor) { if (!bgColor) { return ''; } return (parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2) ? '#000' : '#fff'; } 

我不记得这个代码,因为它不是我的,但是我把它留在这里让别人快速find:

基于Mark Ransoms的回答,下面是简单版本的代码片段:

 function pickTextColorBasedOnBgColorSimple(bgColor, lightColor, darkColor) { var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor; var r = parseInt(color.substring(0, 2), 16); // hexToR var g = parseInt(color.substring(2, 4), 16); // hexToG var b = parseInt(color.substring(4, 6), 16); // hexToB return (((r * 0.299) + (g * 0.587) + (b * 0.114)) > 186) ? darkColor : lightColor; } 

这里是高级版本的代码片段:

 function pickTextColorBasedOnBgColorAdvanced(bgColor, lightColor, darkColor) { var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor; var r = parseInt(color.substring(0, 2), 16); // hexToR var g = parseInt(color.substring(2, 4), 16); // hexToG var b = parseInt(color.substring(4, 6), 16); // hexToB var uicolors = [r / 255, g / 255, b / 255]; var c = uicolors.map((col) => { if (col <= 0.03928) { return col / 12.92; } return Math.pow((col + 0.055) / 1.055, 2.4); }); var L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]); return (L > 0.179) ? darkColor : lightColor; } 

要使用它们只需调用:

 var color = '#EEACAE' // this can be any color pickTextColorBasedOnBgColorSimple(color, '#FFFFFF', '#000000'); 

还有,谢谢Alxchetstone

这是我在Android的Java解决scheme:

 // Put this method in whichever class you deem appropriate // static or non-static, up to you. public static int getContrastColor(int colorIntValue) { int red = Color.red(colorIntValue); int green = Color.green(colorIntValue); int blue = Color.blue(colorIntValue); double lum = (((0.299 * red) + ((0.587 * green) + (0.114 * blue)))); return lum > 186 ? 0xFF000000 : 0xFFFFFFFF; } // Usage // If Color is represented as HEX code: String colorHex = "#484588"; int color = Color.parseColor(colorHex); // Or if color is Integer: int color = 0xFF484588; // Get White (0xFFFFFFFF) or Black (0xFF000000) int contrastColor = WhateverClass.getContrastColor(color); 

这只是一个例子,当点击一个元素时,会改变SVG复选标记的颜色。 它会根据点击元素的背景颜色将复选标记颜色设置为黑色或白色。

 checkmarkColor: function(el) { var self = el; var contrast = function checkContrast(rgb) { // @TODO check for HEX value // Get RGB value between parenthesis, and remove any whitespace rgb = rgb.split(/\(([^)]+)\)/)[1].replace(/ /g, ''); // map RGB values to variables var r = parseInt(rgb.split(',')[0], 10), g = parseInt(rgb.split(',')[1], 10), b = parseInt(rgb.split(',')[2], 10), a; // if RGBA, map alpha to variable (not currently in use) if (rgb.split(',')[3] !== null) { a = parseInt(rgb.split(',')[3], 10); } // calculate contrast of color (standard grayscale algorithmic formula) var contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000; return (contrast >= 128) ? 'black' : 'white'; }; $('#steps .step.color .color-item .icon-ui-checkmark-shadow svg').css({ 'fill': contrast($(self).css('background-color')) }); } onClickExtColor: function(evt) { var self = this; self.checkmarkColor(evt.currentTarget); } 

https://gist.github.com/dcondrey/183971f17808e9277572

我从来没有做过这样的事情,但写一个函数来检查每个颜色的值与hex7F(FF / 2)的中值颜色相对应。 如果三种颜色中的两种颜色大于7F,那么您正在使用较深的颜色。

我使用这个JavaScript函数将rgb / rgba转换为'white''black'

 function getTextColor(rgba) { rgba = rgba.match(/\d+/g); if ((rgba[0] * 0.299) + (rgba[1] * 0.587) + (rgba[2] * 0.114) > 186) { return 'black'; } else { return 'white'; } } 

您可以input任何这些格式,它会输出'black''white'

  • rgb(255,255,255)
  • rgba(255,255,255,0.1)
  • color:rgba(255,255,255,0.1)
  • 255,255,255,0.1

根据@MarkRansom的回答,我创build了一个PHP脚本,你可以在这里find:

 function calcC($c) { if ($c <= 0.03928) { return $c / 12.92; } else { return pow(($c + 0.055) / 1.055, 2.4); } } function cutHex($h) { return ($h[0] == "#") ? substr($h, 1, 7) : $h; } function hexToR($h) { return hexdec(substr(cutHex($h), 0, 2)); } function hexToG($h) { return hexdec(substr(cutHex($h), 2, 4)); } function hexToB($h) { return hexdec(substr(cutHex($h), 4, 6)); } function computeTextColor($color) { $r = hexToR($color); $g = hexToG($color); $b = hexToB($color); $uicolors = [$r / 255, $g / 255, $b / 255]; $c = array_map("calcC", $uicolors); $l = 0.2126 * $c[0] + 0.7152 * $c[1] + 0.0722 * $c[2]; return ($l > 0.179) ? '#000000' : '#ffffff'; } 

除算术解决scheme外,还可以使用AIneural network。 好处是你可以根据自己的口味和需要量身定做(比如饱和的红色的灰白色的文字看起来不错,就像黑色一样可读)。

这是一个简洁的Javascript演示,展示了这个概念。 你也可以在演示中生成你自己的JS公式。

https://harthur.github.io/brain/

下面是一些帮助我解决问题的图表。 在第一张图中,亮度是常数128,而色调和饱和度是变化的。 在第二个图表中,饱和度是常数255,而色调和亮度是不同的。

在第一个图表中,亮度是常数128,而色调和饱和度有所不同:

饱和度是恒定的255,而色调和亮度有所不同:

@SoBiT,我正在看你的答案,看起来不错,但是有一个小错误。 您的函数hexToG和hextoB需要轻微的编辑。 substr中的最后一个数字是string的长度,所以在这种情况下它应该是“2”,而不是4或6。

 function hexToR($h) { return hexdec(substr(cutHex($h), 0, 2)); } function hexToG($h) { return hexdec(substr(cutHex($h), 2, 2)); } function hexToB($h) { return hexdec(substr(cutHex($h), 4, 2)); } 

LESS有一个非常好的contrast()函数,请参阅http://lesscss.org/functions/#color-operations-contrast

“select两种颜色中的哪一种与另一种颜色提供了最大的对比度,这对于确保颜色在背景下可读性是有用的,这对于辅助可达性也是有用的,这个function与用于SASS的罗盘对比度函数的作用相同。根据WCAG 2.0,使用伽马校正的亮度值来比较颜色,而不是亮度。“

例:

 p { a: contrast(#bbbbbb); b: contrast(#222222, #101010); c: contrast(#222222, #101010, #dddddd); d: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 30%); e: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 80%); } 

输出:

 p { a: #000000 // black b: #ffffff // white c: #dddddd d: #000000 // black e: #ffffff // white }