为什么HTML认为”chucknorris”是一种颜色?
当在HTML中作为背景颜色输入时,某些随机字符串如何产生颜色?例如:
<body bgcolor="chucknorris"> test </body>
... 在所有浏览器和平台上生成一个红色背景的文档.
有趣的是,虽然chucknorri
也会产生红色背景,但会chucknorr
产生黄色背景.
这里发生了什么?
回答
这是Netscape日子的延续:
它来自博客文章有点咆哮关于Microsoft Internet Explorer的颜色解析,它详细介绍了它,包括不同长度的颜色值等.
如果我们依次从博客文章中应用规则,我们会得到以下信息:
-
chucknorris becomes c00c0000000
-
c00c 0000 0000
-
RGB (c00c, 0000, 0000)
这给出了以下结果:
RGB (c0, 00, 00) = #C00000 or RGB(192, 0, 0)
这是一个展示bgcolor
行为属性的示例,用于生成这个"惊人"的色样:
<table>
<tr>
<td cellpadding="8" align="center">chuck norris</td>
<td cellpadding="8" align="center">Mr T</td>
<td cellpadding="8" align="center">ninjaturtle</td>
</tr>
<tr>
<td cellpadding="8" align="center">sick</td>
<td cellpadding="8" align="center">crap</td>
<td cellpadding="8" align="center">grass</td>
</tr>
</table>
这也回答了问题的其他部分; 为什么会bgcolor="chucknorr"
产生黄色?好吧,如果我们应用规则,字符串是:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]
这给出了淡黄色的金色.当字符串以9个字符开始时,我们这次保留第二个C因此它最终成为最终颜色值.
当有人指出你可以做的时候,我最初遇到过这个问题color="crap"
,而且它出现了棕色.
- @usr:HTML是故意忽略格式错误的输入;)
- 请注意,尽管该博客帖子说的是,当你处理3-char字符串时,你_duplicate_每个字符,而不是前置0.即`0F6`变为`#00FF66`,而不是#000F06`.
- 您还可以使用我的[random string to css color](http://randomstringtocsscolor.com/)转换器来获取特定字符串的颜色.它基于[Jeremy Goodell计算字符串颜色的5个步骤](http://stackoverflow.com/questions/12939234/why-do-weird-things-in-font-color-attribute-produce-real-colors ).
- @Theraot`bgcolor ="成功"`也是一个不错的绿色.有趣的是,[可以使用CSS属性/值选择器覆盖这些颜色](https://jsfiddle.net/g5meonoz/2/)(例如,`td [bgcolor ="chucknorris"] {...}`).
- 一个隐藏的语义机会?您可以使用以下命令制作一些错误页:`<body bgcolor = error> <h1 style = text-align:center>错误:找不到<h1> </ span>`您可以添加一个div与其他背景或类似的东西,所以它不是那种美学上令人震惊的.
- Fun fact - According to this logic then <body> test </body> would give you the color of a California Taxi Cab! The HQ of Netscape was in Mountain View, California!
- @LưuVĩnhPhúc因为这种方式保留了颜色比例.最终,你将你的颜色转换为最大值的百分比:如果你试图在你的一个通道中转换`f05`,`0xf0/0xff`比`0x05/0xff`更接近`0xf05/0xfff`
- 为什么它从右边截断而不是像计算机中的普通算术那样保持低有效数字呢?
- @戴夫·埃弗里特(Dave Everitt):多年前,我在这里留下了一个类似的轶事(我在对这个问题的评论中提到过),并被标记并删除了两次。这就是生活。
- 您缺少正确计算`<body bgcolor =“ dog”>`的规则:https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-a-legacy-颜色值
- @AaronDufour实际上是合乎逻辑的; 当转换为FF的标度时,在F的标度上最准确的6表示确实是66.如果你不这样做,那么值越大,它就越偏离预期的颜色:FFF,应该是白色,应该变成FFFFFF,而不是F0F0F0.生成16色渐变调色板时遇到此问题.
- @TimPietrusky当我插入名称“ veronica”时,在Chrome和您的转换器中得到了不同的结果
- @DaveEveritt [W3Schools编辑器](https://www.w3schools.com/html/tryit.asp?filename=tryhtml_default)是您的朋友(为此至少)。
我很抱歉不同意,但根据解析@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
已经编辑了他们的答案,包括更正.
- 我想通了,我误解了一些解析说明:"adamlevine"="ada00e000e"="ada00e000e00"="ada0 0e00 0e00"="ad 0e 0e" - 完美!!
- @TimPietrusky为随机颜色名称创建了这个令人难以置信的令人难以置信的演示工具.只需到这里:http://randomstringtocsscolor.com/并点击框并输入"chucknorris".
- 如果你有兴趣,我发布了5步算法作为我今天发布的类似问题的更新:http://stackoverflow.com/questions/12939234/why-do-weird-things-in-font-color -attribute-产生实时的颜色
- `adamlevine`确实按照http://jsfiddle.net/LdyZ8/2959/工作,但这些字母被封锁成`ada00e000e`,填充到'ada00e000e00`但后来减少到典型的HEX 6位数值`[ad ] a0 [0e] 00 [0e] 00`因此使ad0e0e出现在上面的jsfiddle中.
- 如果这个答案***只包含当前状态会更好 - 这个答案的历史和其他答案都属于编辑摘要和/或评论.
大多数浏览器将简单地忽略颜色字符串中的任何NON-hex值,用零替换非十六进制数字.
ChuCknorris
翻译成c00c0000000
.此时,浏览器会将字符串分成三个相等的部分,表示红色,绿色和蓝色值:c00c 0000 0000
.每个部分中的额外位将被忽略,这使得最终结果#c00000
为偏红色.
请注意,这并不能适用于CSS颜色解析,它遵循CSS标准.
<p><font>Redish</font></p>
<p><font>Same as above</font></p>
<p><span>Black</span></p>
- 不跳过无效字符,将它们视为0.
- 虽然我仍然很好奇为什么OP说"在CSS中"而不是"在HTML中" - 也许他们使用的是超级旧的浏览器,或者只是错了?
- 那么他很可能使用已弃用的`bgcolor`属性.
- (这个答案可能已经死了)建议:使用背景颜色代替演示颜色.文本颜色超过这么小的相对区域,很难看出差异或相似之处
- `You might consider editing your answer, because the <font> element is hereby obsolete by HTML5.`
浏览器正在尝试转换chucknorris
为十六进制颜色代码,因为它不是有效值.
- 在
chucknorris
,除了c
有效的十六进制值之外的所有内容. - 所以它被转换为
c00c00000000
. - 哪个变成了#c00000,一个红色的阴影.
这似乎主要是Internet Explorer和Opera(12)的问题,因为Chrome(31)和Firefox(26)都忽略了这一点.
PS括号中的数字是我测试的浏览器版本.
.
更轻松的说明
原因是浏览器无法理解它并尝试以某种方式将其转换为它能理解的内容,在这种情况下转换为十六进制值!...
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";
我还添加了图像中的步骤作为快速参考:
- 这是如此可爱的解释:D:D:D
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;
}
回答:
- 浏览器将尝试将chucknorris转换为十六进制值.
- 由于
c
是chucknorris中唯一有效的十六进制字符,因此该值变为:c00c00000000
(0表示所有无效值). - 然后,浏览器将所述结果为3个groupds: ,
Red = c00c
,.Green = 0000
Blue = 0000
- 由于html背景的有效十六进制值仅包含每种颜色类型(r,g,b)的2位数字,因此最后两位数字将从每个组中截断,其rgb值为
c00000
砖红色调颜色.
查克·诺里斯与统计Ç浏览器读入一个十六进制值.
浏览器chucknorris
转换为C00C00000000
十六进制值.
然后C00C00000000
十六进制值转换为RGB格式(除以3)
浏览器只需要2位数字即可显示颜色.
最后,bgcolor = C00000
在网络浏览器中显示.
这是一个展示的例子
<table>
<tr>
<td cellpadding="10" align="center">chucknorris</td>
<td cellpadding="10" align="center">c00c00000000</td>
<td cellpadding="10" align="center">c00000</td>
</tr>
</table>
- 那是一些非常古老的标记。
The rules for parsing colors on legacy attributes involves additional steps than those mentioned in existing answers. The truncate component to 2 digits part is described as:
- Discard all characters except the last 8
- Discard leading zeros one by one as long as all components have a leading zero
- Discard all characters except the first 2
Some examples:
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
Below is a partial implementation of the algorithm. It does not handle errors or cases where the user enters a valid color.
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 placeholder="Enter color e.g. chucknorris"></p>
<table>
<thead>
<tr>
<th>Left Color</th>
<th>Right Color</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>