在HTML中作为背景色输入时,某些随机字符串如何产生颜色?例如:
<body bgcolor="chucknorris"> test </body>
... 在所有浏览器和平台上产生背景为红色的文档。
有趣的是,虽然chucknorri
也会产生红色背景,但也会chucknorr
产生黄色背景。
这里发生了什么?
在HTML中作为背景色输入时,某些随机字符串如何产生颜色?例如:
<body bgcolor="chucknorris"> test </body>
... 在所有浏览器和平台上产生背景为红色的文档。
有趣的是,虽然chucknorri
也会产生红色背景,但也会chucknorr
产生黄色背景。
这里发生了什么?
chucknorris以c开头,浏览器将其读取为十六进制值。
因为A,B,C,D,E和F是十六进制字符。
浏览器将转换chucknorris
为十六进制值C00C00000000
。
然后将C00C00000000
十六进制值转换为RGB格式(除以3):
C00C00000000
=>R:C00C, G:0000, B:0000
浏览器仅需要两位数字来指示颜色:
R:C00C, G:0000, B:0000
=>R:C0, G:00, B:00
=>C00000
最后,bgcolor = C00000
在Web浏览器中显示。
这是一个演示它的示例:
<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>
回答:
c
是唯一有效的十六进制字符查克·诺里斯,值会变成:c00c00000000
(0为无效的所有值)。Red = c00c
,。Green = 0000
Blue = 0000
c00000
砖红色调的颜色。很抱歉,我不同意,但是根据解析@Yuhong Bao发布的旧色值的规则,chucknorris
不等于#CC0000
,而是等同于#C00000
非常相似但略有不同的红***调。我使用Firefox ColorZilla加载项进行了验证。
规则规定:
chucknorris0
chuc knor ris0
ch kn ri
C0 00 00
我能够使用这些规则正确解释以下字符串:
LuckyCharms
Luck
LuckBeALady
LuckBeALadyTonight
GangnamStyle
更新:说颜色是原来的原始#CC0000
答复者已经编辑了他们的答案以包括更正。
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
例如,请注意,每个字符都被解析为十六进制数字,然后在不检查overflow的情况下被转换为32位整数。32位整数只能容纳8个十六进制数字,这就是为什么只考虑最后8个字符的原因。将十六进制数字解析为32位整数后,然后将它们除以16,直到它们适合8位,然后将其截断为8位整数,这就是为什么忽略前导零的原因。
更新:此代码与规范中定义的代码不完全匹配,但唯一的区别是几行代码。我认为是添加了以下几行(在Netscape 4中):
if (bytes_per_val > 4)
{
bytes_per_val = 4;
}
这是Netscape时代的遗留物:
丢失的数字被视为0 [...]。不正确的数字被简单地解释为0。例如,值#F0F0F0,F0F0F0,F0F0F,#FxFxFx和FxFxFx都相同。
摘自博客文章关于Microsoft Internet Explorer的颜色解析的一点怨言,它详细介绍了它,包括不同长度的颜色值等。
如果我们从博客文章中依次应用规则,则会得到以下信息:
将所有无效的十六进制字符替换为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>
This also answers the other part of the question; why does bgcolor="chucknorr"
produce a yellow colour? Well, if we apply the rules, the string is:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]
Which gives a light yellow gold colour. As the string starts off as 9 characters, we keep the second C this time around hence it ends up in the final colour value.
I originally encountered this when someone pointed out you could do color="crap"
and, well, it comes out brown.
解析旧属性上的颜色的规则涉及到比现有答案中提到的步骤更多的步骤。将截断部分转换为2位数部分描述为:
一些例子:
以下是该算法的部分实现。它不处理错误或用户输入有效颜色的情况。