在HTML中作为背景色输入时,某些随机字符串如何产生颜色?例如:
<body bgcolor="chucknorris"> test </body>
... 在所有浏览器和平台上产生背景为红色的文档。
有趣的是,虽然chucknorri
也会产生红色背景,但也会chucknorr
产生黄色背景。
这里发生了什么?
chucknorris
?预期的颜色是什么?
<body bgcolor="stevensegal">
测试</ body>为绿色
在HTML中作为背景色输入时,某些随机字符串如何产生颜色?例如:
<body bgcolor="chucknorris"> test </body>
... 在所有浏览器和平台上产生背景为红色的文档。
有趣的是,虽然chucknorri
也会产生红色背景,但也会chucknorr
产生黄色背景。
这里发生了什么?
chucknorris
?预期的颜色是什么?
<body bgcolor="stevensegal">
测试</ body>为绿色
Answers:
这是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>
这也回答了问题的另一部分。为什么会bgcolor="chucknorr"
产生黄色?好吧,如果我们应用规则,则字符串为:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]
呈浅金黄色。由于字符串以9个字符开头,因此我们这次保留了第二个C,因此最终以最终的颜色值结束。
当有人指出您可以做到时,我最初遇到了这个问题color="crap"
,但是,结果变成了褐色。
0F6
变为#00FF66
,而不是#000F06
。
<body bgcolor=error><h1 style=text-align:center>Error: Not Found<h1></span>
您可以添加一个带有背景或类似背景的div,因此在美学上并不那么令人震惊。
很抱歉,我不同意,但是根据解析@Yuhong Bao发布的旧色值的规则,chucknorris
不等于#CC0000
,而是等同于#C00000
非常相似但略有不同的红色色调。我使用Firefox ColorZilla加载项进行了验证。
规则规定:
chucknorris0
chuc knor ris0
ch kn ri
C0 00 00
我能够使用这些规则正确解释以下字符串:
LuckyCharms
Luck
LuckBeALady
LuckBeALadyTonight
GangnamStyle
更新:说颜色是原来的原始#CC0000
答复者已经编辑了他们的答案以包括更正。
adamlevine
确实按照jsfiddle.net/LdyZ8/2959的要求工作,但字母被ada00e000e
填充到其中,ada00e000e00
然后降低到典型的十六进制6位数字值,[ad]a0[0e]00[0e]00
从而使ad0e0e出现在上面的jsfiddle中。
大多数浏览器将只忽略颜色字符串中的任何非十六进制值,而将非十六进制数字替换为零。
ChuCknorris
转换为c00c0000000
。此时,浏览器会将字符串分为三个相等的部分,分别指示Red,Green和Blue值: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>
bgcolor
属性。
原因是浏览器无法理解它,并尝试以某种方式将其转换为可以理解的值,在这种情况下,将其转换为十六进制值!
chucknorris
开头为c
已识别的十六进制字符,还将所有无法识别的字符转换为0
!
因此,chucknorris
以十六进制格式变为:c00c00000000
,所有其他字符变为0
并c
保持原样...
现在,它们被3除以RGB
(红色,绿色,蓝色)... R: c00c, G: 0000, B:0000
...
但是我们知道RGB的有效十六进制只有2个字符,这意味着 R: c0, G: 00, B:00
因此,实际结果是:
bgcolor="#c00000";
我还将图像中的步骤添加为您的快速参考:
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;
}
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>
解析旧属性上的颜色的规则涉及到比现有答案中提到的步骤更多的步骤。将截断部分转换为2位数部分描述为:
一些例子:
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
以下是该算法的部分实现。它不处理错误或用户输入有效颜色的情况。
bgcolor
。使用CSSbackground
。