Why does HTML think “chucknorris” is a color?

Why does HTML think “chucknorris” is a color?

技术背景

在早期的网页开发中,Netscape 浏览器制定了一些关于颜色值解析的规则。这些规则在后续的浏览器发展中部分被保留下来,导致了一些有趣的现象,例如 HTML 会将 “chucknorris” 这样的字符串解析为颜色。这种解析规则主要应用于 HTML 标签的颜色属性,如 bgcolorcolor,但在 CSS 颜色解析中并不适用,CSS 遵循 CSS 标准。

实现步骤

颜色解析规则

  1. 替换非十六进制字符:将字符串中所有非有效的十六进制字符替换为 0。例如,“chucknorris” 会变成 “c00c0000000”。
  2. 补齐字符长度:将字符串的长度补齐为能被 3 整除的最小长度。对于 “c00c0000000”,长度为 11,补齐后变为 “c00c 0000 0000”。
  3. 分割为 RGB 分量:将补齐后的字符串平均分割为三组,每组对应 RGB 颜色的一个分量。即 “RGB (c00c, 0000, 0000)”。
  4. 截断每个分量:将每个分量从右向左截断为两个字符。最终得到 “RGB (c0, 00, 00)”,对应的十六进制颜色值为 “#C00000”,即 RGB(192, 0, 0)。

不同字符串的解析示例

  • “chucknorr”:“chucknorr” 经过上述规则处理后,“c00c00000” => “c00 c00 000” => “c0 c0 00” [RGB(192, 192, 0)],呈现出浅黄色。
  • “Rajnikanth”:转换为十六进制格式为 “0a00 00a0 0000”,最终结果为 “#0a0000”,是一种黑色调。

核心代码

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

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 来设置颜色,遵循 CSS 标准,避免使用 HTML 标签的 bgcolorcolor 属性,以提高代码的兼容性和可维护性。
  • 如果需要处理用户输入的颜色值,可使用上述解析函数进行处理,但要注意完善错误处理和边界情况的判断。

常见问题

浏览器兼容性问题

这种颜色解析规则主要在 Internet Explorer 和 Opera(12)等浏览器中存在,Chrome(31)和 Firefox(26)等浏览器会直接忽略无效的颜色值。因此,在开发过程中要注意不同浏览器的表现差异。

与 CSS 标准冲突

CSS 有自己的颜色解析标准,与 HTML 遗留的颜色解析规则不同。在使用时要明确区分,避免混淆。例如,在 CSS 中使用 color: chucknorris 会被解析为无效值,元素颜色通常会显示为黑色。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1010n111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值