HTMLで背景色として入力したときに、特定のランダムな文字列が色を生成するのはどうしてですか?例えば:
<body bgcolor="chucknorris"> test </body>
...すべてのブラウザとプラットフォームで、 赤い背景 のドキュメントが生成されます。
興味深いことに、chucknorri
は赤の背景も生成しますが、chucknorr
は黄色の背景を生成します。
何が起きてる?
これは、Netscapeの時代からの延期です。
欠けている数字は0 [...]として扱われます。たとえば、#F0F0F0、F0F0F0、F0F0F、#FxFxFx、FxFxFxの値はすべて同じです。
これはブログの投稿からです。Microsoft Internet Explorerの色解析について少し学びましたさまざまな長さの色の値など、詳細に説明されています。
ブログ投稿から順番にルールを適用すると、次のようになります。
無効な16進文字をすべて0に置き換えます。
chucknorris becomes c00c0000000
3で割り切れる次の合計文字数までパディングします(11 - > 12)。
c00c 0000 0000
各成分がRGBカラーの対応するカラー成分を表すように、3つの等しいグループに分割します。
RGB (c00c, 0000, 0000)
各引数を右から2文字に切り捨てます
これにより、次の結果が得られます。
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文字から始まるので、今回は2番目のCを保持して、最終的な色の値にします。
誰かがあなたがcolor="crap"
をすることができると指摘したとき、私はもともとこれに遭遇しました、そして、まあ、それは茶色になります。
同意しないで申し訳ありませんが、 @Yuhong Bao によって投稿されたレガシーカラー値を解析するための規則によれば、chucknorris
は#CC0000
と同じではなく、むしろ#C00000
と同じですが、わずかに異なる赤の色相です。これを確認するために Firefox ColorZillaアドオン を使用しました。
規則は次のように述べています。
chucknorris0
chuc knor ris0
ch kn ri
C0 00 00
これらの規則を使用して、次の文字列を正しく解釈することができました。
LuckyCharms
Luck
LuckBeALady
LuckBeALadyTonight
GangnamStyle
UPDATE: 色が#CC0000
であると言った元の回答者は、それ以来修正を含むように回答を編集しました。
ほとんどのブラウザは、あなたのカラー文字列の中の16進数でない数字をゼロで置き換えて、16進数でない値を単に無視するでしょう。
ChuCknorris
はc00c0000000
に変換されます。この時点で、ブラウザは文字列を3つの等しいセクションに分割し、Red、Green、およびBlueの値を示します:c00c 0000 0000
。各セクションの余分なビットは無視され、赤みを帯びた色の最終結果#c00000
になります。
これはnotが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
を16進カラーコードに変換しようとしています。これは有効な値ではないためです。
chucknorris
では、c
以外のすべてが有効な16進値ではありません。c00c00000000
に変換されます。Chrome(31)とFirefox(26)は両方とも無視しているので、これは主に Internet Explorer および Opera (12)の問題です。
P.S括弧内の数字は私がテストしたブラウザのバージョンです。
。
軽いメモ
Chuck NorrisはWeb標準に準拠していません。 Web標準は彼に準拠しています。 #BADA55
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
たとえば、各文字は16進数として解析され、32ビット整数オーバーフローをチェックせずににシフトされることに注意してください。 32ビット整数に収まるのは8桁の16進数字だけです。これが、最後の8文字だけが考慮される理由です。 16進数を32ビット整数に解析した後、それらが8ビットに収まるまで16で除算することによって8ビット整数に切り捨てられます。そのため、先行ゼロは無視されます。
更新:このコードは仕様で定義されているものと完全には一致しませんが、異なる点は数行のコードです。 (Netscape 4で)追加されたのはこれらの行だと思います。
if (bytes_per_val > 4)
{
bytes_per_val = 4;
}
その理由は、ブラウザが 理解できない それを理解し、この場合は16進値に変換できるようにするためです。
chucknorris
name__はc
name__で始まります。これは16進数の文字として認識され、認識されないすべての文字を0
に変換します。
そのため、16進形式のchucknorris
name__はc00c00000000
になり、他のすべての文字は0
になり、c
name__はそのままの位置に残ります。
これで、RGB
name __(赤、緑、青)について3で割られるようになりました... R: c00c, G: 0000, B:0000
...
しかし、RGBの有効な16進数は2文字に過ぎないことがわかっています。つまり、R: c0, G: 00, B:00
です。
実際の結果はこうなります:
bgcolor="#c00000";
また、クイックリファレンスとして画像に手順を追加しました。
回答:
c
はchucknorrisで唯一の有効な16進文字なので、値は次のようになります。c00c00000000
(無効だったすべての値に対して0)。Red = c00c
、Green = 0000
、Blue = 0000
に分割します。c00000
のrgb値を残します。chucknorris は c の統計で、ブラウザは16進値を読み込みます。
a、b、c、d、e、fは 16進数の文字です
ブラウザのchucknorris
はc00c00000000
の16進値に変換されます。
それからc00c00000000
の16進値を _ rgb _ 形式に変換します(3で除算)
c00c00000000
=>R:c00c,G:0000,B:0000
ブラウザは、色を表すのに2桁しか必要ありません。
R:c00c,G:0000,B:0000
=>R:c0,G:00,B:00
=>c00000
最後に、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>
従来の属性の色を解析するための規則 は、既存の回答で述べられているものよりも追加のステップを含みます。 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 e.g. chucknorris"></p>
<table id="result">
<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>