为什么HTML认为“chucknorris”是一种颜色?

问题描述 投票:7000回答:9

当在HTML中作为背景颜色输入时,某些随机字符串如何产生颜色?例如:

<body bgcolor="chucknorris"> test </body>

...在所有浏览器和平台上生成一个红色背景的文档。

有趣的是,虽然chucknorri也产生红色背景,但chucknorr产生黄色背景。

这里发生了什么?

html css background-color
9个回答
6560
投票

这是Netscape日子的延续:

丢失的数字被视为0 [...]。不正确的数字简单地解释为0.例如,值#F0F0F0,F0F0F0,F0F0F,#FxFxFx和FxFxFx都是相同的。

它来自博客文章A little rant about Microsoft Internet Explorer's color parsing,它详细介绍了它,包括不同长度的颜色值等。

如果我们依次从博客文章中应用规则,我们会得到以下信息:

  1. 用0替换所有无效的十六进制字符 qazxsw poi
  2. 填写下一个可被3整除的字符总数(11 - > 12) chucknorris becomes c00c0000000
  3. 分成三个相等的组,每个组件代表RGB颜色的相应颜色分量: c00c 0000 0000
  4. 将每个参数从右向下截断为两个字符

这给出了以下结果:

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"

这给出了淡黄色的金色。当字符串以9个字符开始时,我们这次保留第二个C因此它最终成为最终颜色值。

当有人指出你可以做c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)] 时,我最初遇到这个,而且,它出来了棕色。


909
投票

我很抱歉不同意,但根据解析color="crap"发布的遗留颜色值的规则,@Yuhong Bao不等于chucknorris,而是等同于#CC0000,一种非常相似但略有不同的红色色调。我使用#C00000来验证这一点。

规则规定:

  • 通过添加0来使字符串的长度为3的倍数:Firefox ColorZilla add-on
  • 将字符串分成3个相等长度的字符串:chucknorris0
  • 将每个字符串截断为2个字符:chuc knor ris0
  • 保留十六进制值,并在必要时添加0:ch kn ri

我能够使用这些规则来正确解释以下字符串:

  • C0 00 00
  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight

更新:原来的回答说,颜色是GangnamStyle已经编辑了他们的答案,包括更正。


369
投票

大多数浏览器将简单地忽略颜色字符串中的任何NON-hex值,用零替换非十六进制数字。

#CC0000翻译为ChuCknorris。此时,浏览器会将字符串分成三个相等的部分,表示红色,绿色和蓝色值:c00c0000000。每个部分中的额外位将被忽略,这使得最终结果c00c 0000 0000是一个偏红的颜色。

注意,这不适用于符合CSS标准的CSS颜色解析。

#c00000

274
投票

浏览器正在尝试将<p><font color='chucknorris'>Redish</font></p> <p><font color='#c00000'>Same as above</font></p> <p><span style="color: chucknorris">Black</span></p>转换为十六进制颜色代码,因为它不是有效值。

  1. chucknorris中,除chucknorris之外的所有内容都不是有效的十六进制值。
  2. 所以它被转换为c
  3. 哪个变成了#c00000,一个红色的阴影。

这似乎主要是Internet Explorer和Opera(12)的问题,因为Chrome(31)和Firefox(26)都忽略了这一点。

附:括号中的数字是我测试的浏览器版本。

.

更轻松的说明

查克诺里斯不符合网络标准。 Web标准符合他的要求。 #BADA55


230
投票

原因是浏览器无法理解它并尝试以某种方式将其转换为它能理解的内容,在这种情况下转换为十六进制值!...

c00c00000000chucknorris开头,c是十六进制中识别的字符,也是将所有未识别的字符转换为0

所以十六进制格式的chucknorris变成:c00c00000000,所有其他角色变成0c仍然在哪里...

现在他们被RGB(红色,绿色,蓝色)除以3 ... R: c00c, G: 0000, B:0000 ...

但我们知道RGB的有效十六进制只有2个字符,意思是R: c0, G: 00, B:00

所以真正的结果是:

bgcolor="#c00000";

我还在图像中添加了步骤作为快速参考:

Why does HTML think “chucknorris” is a color?


207
投票

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;
}

188
投票

回答:

  • 浏览器将尝试将chucknorris转换为十六进制值。
  • 由于c是chucknorris中唯一有效的十六进制字符,因此该值变为:c00c00000000(0表示所有无效值)。
  • 浏览器然后将结果分为3组:qazxsw poi,qazxsw poi,qazxsw poi。
  • 由于html背景的有效十六进制值仅包含每种颜色类型(r,g,b)的2位数字,因此从每个组中截断最后2位数字,留下rgb值Red = c00c,这是一种砖红色调颜色。

12
投票

chucknorris以c开头,浏览器将其读入十六进制值。

因为A,B,C,D,E和F是Green = 0000

浏览器将Blue = 0000转换为十六进制值c00000

然后将characters in hexadecimal十六进制值转换为RGB格式(除以3):

chucknorris => C00C00000000

浏览器只需要两位数字来表示颜色:

C00C00000000 => C00C00000000 => R:C00C, G:0000, B:0000

最后,在Web浏览器中显示R:C00C, G:0000, B:0000

这是一个展示它的例子:

R:C0, G:00, B:00

7
投票

C00000涉及的步骤不同于现有答案中提到的步骤。截断组件为2位数部分描述为:

  1. 丢弃除最后8个之外的所有字符
  2. 只要所有组件都具有前导零,就逐个丢弃前导零
  3. 丢弃除前2个之外的所有字符

一些例子:

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>
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
© www.soinside.com 2019 - 2024. All rights reserved.