繁体   English   中英

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

Why does HTML think “chucknorris” is a color?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

为什么某些随机字符串在 HTML 中作为背景 colors 输入时会产生 colors?

例如, bgcolor="chucknorris"产生红色背景

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

相反, bgcolor="chucknorr"产生黄色背景

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

这适用于各种浏览器和平台。 这里发生了什么?

9 个回复

这是网景时代的遗留物:

缺少的数字被视为 0[...]。 错误的数字被简单地解释为 0。例如,#F0F0F0、F0F0F0、F0F0F、#FxFxFx 和 FxFxFx 的值都是相同的。

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

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

  1. 用 0 替换所有无效的十六进制字符:

     chucknorris becomes c00c0000000
  2. 填充到下一个可被 3 整除的字符总数 (11 → 12):

     c00c 0000 0000
  3. 分成三个相等的组,每个分量代表 RGB 颜色的相应颜色分量:

     RGB (c00c, 0000, 0000)
  4. 将每个参数从右边截断为两个字符。

最后,得出以下结果:

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"时,我最初遇到了这个,好吧,它是棕色的。

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

规则规定:

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

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

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle

更新:说颜色是#CC0000的原始回答者已经编辑了他们的答案以包括更正。

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

chucknorrisc开头,这是十六进制可识别的字符,还将所有无法识别的字符转换为0

因此, chucknorris以十六进制格式变为: c00c00000000 ,所有其他人物变成0c遗体他们在哪里?

现在它们除以 3 表示RGB (红、绿、蓝)... R: c00c, G: 0000, B:0000 ...

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

所以真正的结果是:

bgcolor="#c00000";

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

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

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

ChuCknorris转换为c00c0000000 此时,浏览器会将字符串分成三个相等的部分,分别表示RedGreenBlue值: 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>

浏览器正在尝试将chucknorris转换为十六进制颜色代码,因为它不是一个有效值。

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

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

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

轻描淡写

Chuck Norris 不符合网络标准。 网络标准符合他。 #BADA55

WHATWG HTML 规范具有解析旧颜色值的精确算法: https : //html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

用于解析颜色字符串的 Netscape Classic 代码是开源的: https : //github.com/zii/netscape/blob/master/lib/layout/layimage.c#L150

例如,请注意每个字符都被解析为一个十六进制数字,然后被移入一个 32 位整数而不检查溢出 只有 8 个十六进制数字适合 32 位整数,这就是为什么只考虑最后 8 个字符的原因。 在将十六进制数字解析为 32 位整数后,然后将它们除以 16 直到它们适合 8 位,从而将它们截断为 8 位整数,这就是忽略前导零的原因。

更新:此代码与规范中定义的不完全匹配,但唯一的区别是几行代码。 我认为是添加了这些行(在 Netscape 中):

if (bytes_per_val > 4)
{
    bytes_per_val = 4;
}

回答:

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

chucknorrisc开头,浏览器将其读入一个十六进制值。

因为 A、B、C、D、E 和 F 是十六进制字符

浏览器将chucknorris转换为十六进制值C00C00000000

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

C00C00000000R:C00C, G:0000, B:0000

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

R:C00C, G:0000, B:0000R:C0, G:00, B:00C00000

最后,在 Web 浏览器中显示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>

解析旧属性颜色规则涉及比现有答案中提到的步骤更多的步骤。 truncate 组件到 2 位部分描述为:

  1. 丢弃除最后 8 个字符以外的所有字符
  2. 只要所有组件都有前导零,就一一丢弃前导零
  3. 丢弃除前 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

下面是该算法的部分实现。 它不处理错误或用户输入有效颜色的情况。

 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); }); });
 body { font: medium monospace; } input { width: 20em; } table { table-layout: fixed; width: 100%; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <p><input id="input" placeholder="Enter color eg chucknorris"></p> <table id="result"> <thead> <tr> <th>Left Color</th> <th>Right Color</th> </tr> </thead> <tbody> <tr> <td>&nbsp;</td> <td>&nbsp;</td> </tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td> </tr> </tbody> </table>

用简单的话回答:

简短的回答是 HTML 非常渴望取悦,并且基本上会接受您提供的任何内容。 HTML 是围绕有意忽略格式错误的输入而构建的。

整体概念:

HTML 接受非十六进制字符为 0,所以我们都知道 0-9 定义了 0 到 9,然后 AF 定义了 10 到 15。 所以有很多单词可以是像“chucknorris”这样的深血红色。 同样“stevensegal”的意思是绿色。

显示意外的颜色:如果您在 bgcolor 中放置任何包含几个十六进制字符的单词,那么该字符将向您显示一些您从未想过的意外颜色。 它的工作原理就像#F00F00等于#FotFot 但这仅适用于 table 标签内的 bgcolor 无处可去。

演示:

 <style> h1 { color: green; } </style>
 <center> <h1>Why HTML thinks Chucknorris as color?</h1> <p> Here is the implementation...!!! </p> <table> It is the color of: <td bgcolor="chucknorris"> chucknorris </td> </table> </center>

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

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

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

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

这里发生了什么?

这是因为十六进制的“ chucknorris”仅为255000000。它等效于以下代码:

<p><font color='red'>Redish</font><p>
2 将rgb的一种颜色转换为图像HTML 5画布的另一种颜色

我的游戏有以HTML 5和javascript开发的png图片。 我想给它不同的颜色。 图像有4种不同的颜色。 我想将每种颜色转移到其他颜色。 我知道如何在HTML5画布中更改颜色,但不知道两个如何将最后三个颜色与第一个联系起来。 我有谷歌的颜色转换,但没有发现有帮助。 谢 ...

3 HTML5 Canvas从一种颜色平滑过渡到另一种颜色

有没有办法从一种颜色平稳过渡到另一种颜色? 例如,蓝色到红色。 我有一个数组,将循环约125次。 在这个数组中,我想将颜色从蓝色过渡到红色。 我是否必须在自己的数组中具有125个不同的颜色值,然后在索引循环时选择每个颜色值? ...

4 更改贴片颜色(一种颜色除外)

我正在Netlogo中创建一个程序,使购物者(海龟)在杂货店的布局中移动。 当他们踩到一块补丁时,颜色会增加,而当上面没有代理商时,颜色会减少,因为这将显示购物者通过商店的路径。 我的代码是: 但是,由于过道补丁是蓝色的,这也会将它们也变回黑色。 我想知道我可以使用什么样的代码 ...

2016-02-09 05:04:08 1 53   netlogo
6 如何一次检测一个 colors

我需要检测两个colors,一个接一个。 所以这是我的程序工作流程的一个例子: 检测并使用特定颜色的 object,然后 object 与相机足够接近(指定多少), 程序应该尝试开始寻找另一种颜色。 这是我到目前为止所尝试的# All python's imports vs = VideoStr ...

8 MATLAB:image()仅显示一种颜色

输出的图像是默认值:全红色。 如何使颜色条在图像中显示正确的值范围(即1301-1500),并且图像的每个像素显示正确的值? 谢谢! 编辑:答案:imagesc(B) ...

9 将白色混合成一种颜色

我有一组在RBG和CMYK中指定的颜色。 我想将一定数量的白色(百分比)添加到这些颜色中。 如何根据可用的表示执行此操作? 有人可以推荐一个可以帮助我进行这种颜色转换的软件包吗? ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM