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

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

技术背景

在HTML中,当我们为元素(如<body>)的bgcolor属性指定值时,通常会使用标准的颜色名称(如red)或十六进制颜色代码(如#FF0000)。然而,令人惊讶的是,某些随机字符串(如“chucknorris”)也能产生颜色效果,这一现象在不同浏览器和平台上都存在。

实现步骤

1. 替换非十六进制字符

浏览器会将字符串中的所有非有效十六进制字符替换为0。对于“chucknorris”,替换后变为“c00c0000000”。

2. 填充字符串

将字符串填充到长度能被3整除。“c00c0000000”的长度为11,填充为12个字符后变为“c00c 0000 0000”。

3. 分割字符串

将填充后的字符串分割成三个相等的组,每个组代表RGB颜色的一个分量。即“RGB (c00c, 0000, 0000)”。

4. 截断每个分量

从右侧将每个分量截断为两个字符。最终得到“RGB (c0, 00, 00)”,即#C00000RGB(192, 0, 0),这是一种红色。

对于“chucknorr”,替换后为“c00c00000”,填充并分割后为“c00 c00 000”,截断后为“c0 c0 00”,即RGB(192, 192, 0),呈现为浅黄色。

核心代码

以下是一个简单的HTML示例,展示了不同字符串作为bgcolor属性值的效果:

1
2
3
4
5
6
7
8
9
10
11
12
<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>

以下是一个部分实现颜色解析算法的JavaScript代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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);
});
});

最佳实践

  • 避免使用非标准颜色字符串:虽然浏览器支持这种非标准的颜色解析方式,但为了代码的可读性和兼容性,建议使用标准的颜色名称或十六进制颜色代码。
  • 使用CSS替代bgcolor属性bgcolor属性已经被HTML5标记为过时,推荐使用CSS的background-color属性来设置元素的背景颜色。

常见问题

不同浏览器的表现是否一致?

大部分现代浏览器在颜色解析上遵循相似的规则,但仍可能存在细微差异。例如,在早期版本中,某些浏览器可能对非标准颜色字符串的处理方式略有不同。

CSS颜色解析是否也遵循相同规则?

不,CSS颜色解析遵循CSS标准,不会对非标准字符串进行类似的处理。例如,在CSS中使用color: chucknorris会被视为无效值,元素的颜色不会改变。


为何HTML认为“chucknorris”是一种颜色?
https://119291.xyz/posts/2025-04-15.why-html-thinks-chucknorris-is-a-color/
作者
ww
发布于
2025年4月15日
许可协议