当在HTML中作为背景颜色输入时,某些随机字符串是如何产生颜色的?例如:
<body bgcolor="chucknorris"> test </body>
...在所有浏览器和平台上生成一个红色背景的文档。
有趣的是,虽然chucknorri
也会产生红色背景,但chucknorr
会产生黄色背景。
这里发生了什么?
答案 0 :(得分:6468)
这是Netscape时代的延续:
缺少数字被视为0 [...]。不正确的数字简单地解释为0.例如,值#F0F0F0,F0F0F0,F0F0F,#FxFxFx和FxFxFx都是相同的。
来自博客文章 A little rant about Microsoft Internet Explorer's color parsing ,其中详细介绍了它,包括不同长度的颜色值等。
如果我们依次从博客文章中应用规则,我们会收到以下信息:
将所有无效的十六进制字符替换为0
chucknorris becomes c00c0000000
填写下一个可被3整除的字符总数(11 - > 12)
c00c 0000 0000
分成三个相等的组,每个组件代表RGB颜色的相应颜色分量:
RGB (c00c, 0000, 0000)
将每个参数从右向下截断为两个字符
这给出了以下结果:
RGB (c0, 00, 00) = #C00000 or RGB(192, 0, 0)
这是一个展示bgcolor
属性的示例,用于制作这个“惊人的”色样:
<table>
<tr>
<td bgcolor="chucknorris" cellpadding="8" width="100" align="center">chuck norris</td>
<td bgcolor="mrt" cellpadding="8" width="100" align="center" style="color:#ffffff">Mr T</td>
<td bgcolor="ninjaturtle" cellpadding="8" width="100" align="center" style="color:#ffffff">ninjaturtle</td>
</tr>
<tr>
<td bgcolor="sick" cellpadding="8" width="100" align="center">sick</td>
<td bgcolor="crap" cellpadding="8" width="100" align="center">crap</td>
<td bgcolor="grass" cellpadding="8" width="100" align="center">grass</td>
</tr>
</table>
这也回答了问题的其他部分;为什么bgcolor="chucknorr"
会产生黄色?好吧,如果我们应用规则,字符串是:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]
这给出了淡黄色的金色。当字符串以9个字符开头时,我们这次保留第二个C,因此它最终会出现在最终的颜色值中。
当有人指出你可以做color="crap"
时,我最初遇到过这种情况,而且,它是褐色的。
答案 1 :(得分:894)
我很抱歉不同意,但根据解析@Yuhong Bao发布的旧版颜色值的规则,chucknorris
不等于#CC0000
,而是{{1}红色的一种非常相似但略有不同的色调。我使用Firefox ColorZilla add-on来验证这一点。
规则声明:
#C00000
chucknorris0
chuc knor ris0
ch kn ri
我能够使用这些规则正确解释以下字符串:
C0 00 00
LuckyCharms
Luck
LuckBeALady
LuckBeALadyTonight
更新:表示颜色为GangnamStyle
的原始回答者已经编辑了他们的答案以包含更正。
答案 2 :(得分:363)
大多数浏览器只会忽略颜色字符串中的任何非十六进制值,用零替换非十六进制数字。
ChuCknorris
转换为c00c0000000
。此时,浏览器会将字符串分成三个相等的部分,表示红色,绿色和蓝色值:c00c 0000 0000
。每个部分中的额外位将被忽略,这使得最终结果#c00000
呈现偏红色。
注意,不适用于符合CSS标准的CSS颜色解析。
<p><font color='chucknorris'>Redish</font></p>
<p><font color='#c00000'>Same as above</font></p>
<p><span style="color: chucknorris">Black</span></p>
答案 3 :(得分:267)
浏览器正在尝试将chucknorris
转换为十六进制颜色代码,因为它不是有效值。
chucknorris
中,除 c
以外的所有内容都不是有效的十六进制值。c00c00000000
。 这似乎主要是针对 Internet Explorer 和 Opera (12)的问题,因为Chrome(31)和Firefox(26)都忽略了这一点。
P.S。括号中的数字是我测试的浏览器版本。
更轻松的说明
查克诺里斯不符合网络标准。 Web标准符合 给他。 #BADA55
答案 4 :(得分:205)
WHATWG HTML规范具有解析旧版颜色值的确切算法: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value
用于解析颜色字符串的Netscape Classic代码是开源的: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155
例如,请注意每个字符都被解析为十六进制数字,然后转换为32位整数而不检查溢出。只有八个十六进制数字适合32位整数,这就是为什么只考虑最后8个字符的原因。将十六进制数字解析为32位整数后,将它们除以16,直到它们适合8位,将它们截断为8位整数,这就是忽略前导零的原因。
更新:此代码与规范中定义的内容不完全匹配,但唯一的区别是几行代码。我认为这些线路被添加(在Netscape 4中):
if (bytes_per_val > 4)
{
bytes_per_val = 4;
}
答案 5 :(得分:205)
原因是浏览器可以不理解它并尝试以某种方式将其转换为它可以理解的内容,在这种情况下转换为十六进制值!...
chucknorris
以c
开头,它是十六进制中的已识别字符,也是将所有无法识别的字符转换为0
!
因此,十六进制格式的chucknorris
变为:c00c00000000
,所有其他字符变为0
,而c
仍然保留在...... {/ p>
现在他们被RGB
(红色,绿色,蓝色)除以3 ...... R: c00c, G: 0000, B:0000
......
但我们知道RGB的有效十六进制只有2个字符,意味着R: c0, G: 00, B:00
所以真正的结果是:
bgcolor="#c00000";
我还在图片中添加了步骤作为快速参考:
答案 6 :(得分:186)
答案:
c
是 chucknorris 中唯一有效的十六进制字符,因此该值变为:c00c00000000
( 0表示所有无效值 )。 Red = c00c
,Green = 0000
,Blue = 0000
。c00000
,这是一种砖红色调。答案 7 :(得分:12)
chucknorris 是 c 的统计信息,浏览器会将其读入十六进制值。
因为a,b,c,d,e,f是characters in hexadecimal
浏览器chucknorris
转换为c00c00000000
十六进制值。
然后c00c00000000
十六进制值转换为 RGB 格式(除以3)
c00c00000000
=&gt;R:c00c,G:0000,B:0000
浏览器只需要2位数字即可显示颜色。
R:c00c,G:0000,B:0000
=&gt;R:c0,G:00,B:00
=&gt;c00000
最后,在网络浏览器中显示bgcolor = c00000
。
以下是演示
的示例
<table>
<tr>
<td bgcolor="chucknorris" cellpadding="10" width="150" align="center">chucknorris</td>
<td bgcolor="c00c00000000" cellpadding="10" width="150" align="center">c00c00000000</td>
<td bgcolor="c00000" cellpadding="10" width="150" align="center">c00000</td>
</tr>
</table>
答案 8 :(得分:6)
rules for parsing colors on legacy attributes涉及除现有答案中提到的步骤之外的其他步骤。将截断部分转换为两位数的部分描述为:
一些例子:
oooFoooFoooF
000F 000F 000F <- replace, pad and chunk
0F 0F 0F <- leading zeros truncated
0F 0F 0F <- truncated to 2 characters from right
oooFooFFoFFF
000F 00FF 0FFF <- replace, pad and chunk
00F 0FF FFF <- leading zeros truncated
00 0F FF <- truncated to 2 characters from right
ABCooooooABCooooooABCoooooo
ABC000000 ABC000000 ABC000000 <- replace, pad and chunk
BC000000 BC000000 BC000000 <- truncated to 8 characters from left
BC BC BC <- truncated to 2 characters from right
AoCooooooAoCooooooAoCoooooo
A0C000000 A0C000000 A0C000000 <- replace, pad and chunk
0C000000 0C000000 0C000000 <- truncated to 8 characters from left
C000000 C000000 C000000 <- leading zeros truncated
C0 C0 C0 <- truncated to 2 characters from right
下面是该算法的部分实现。它不处理错误或用户输入有效颜色的情况。
function parseColor(input) {
// todo: return error if input is ""
input = input.trim();
// todo: return error if input is "transparent"
// todo: return corresponding #rrggbb if input is a named color
// todo: return #rrggbb if input matches #rgb
// todo: replace unicode code points greater than U+FFFF with 00
if (input.length > 128) {
input = input.slice(0, 128);
}
if (input.charAt(0) === "#") {
input = input.slice(1);
}
input = input.replace(/[^0-9A-Fa-f]/g, "0");
while (input.length === 0 || input.length % 3 > 0) {
input += "0";
}
var r = input.slice(0, input.length / 3);
var g = input.slice(input.length / 3, input.length * 2 / 3);
var b = input.slice(input.length * 2 / 3);
if (r.length > 8) {
r = r.slice(-8);
g = g.slice(-8);
b = b.slice(-8);
}
while (r.length > 2 && r.charAt(0) === "0" && g.charAt(0) === "0" && b.charAt(0) === "0") {
r = r.slice(1);
g = g.slice(1);
b = b.slice(1);
}
if (r.length > 2) {
r = r.slice(0, 2);
g = g.slice(0, 2);
b = b.slice(0, 2);
}
return "#" + r.padStart(2, "0") + g.padStart(2, "0") + b.padStart(2, "0");
}
$(function() {
$("#input").on("change", function() {
var input = $(this).val();
var color = parseColor(input);
var $cells = $("#result tbody td");
$cells.eq(0).attr("bgcolor", input);
$cells.eq(1).attr("bgcolor", color);
var color1 = $cells.eq(0).css("background-color");
var color2 = $cells.eq(1).css("background-color");
$cells.eq(2).empty().append("bgcolor: " + input, "<br>", "getComputedStyle: " + color1);
$cells.eq(3).empty().append("bgcolor: " + color, "<br>", "getComputedStyle: " + color2);
});
});
body { font: medium monospace; }
input { width: 20em; }
table { table-layout: fixed; width: 100%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<p><input id="input" placeholder="Enter color e.g. chucknorris"></p>
<table id="result">
<thead>
<tr>
<th>Left Color</th>
<th>Right Color</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>