HTMLの背景色として、あるランダムな文字列を入力すると色が出るのはなぜですか?例えば、以下のようなものです。
<body bgcolor="chucknorris"> test </body>
...すべてのブラウザとプラットフォームで 赤い背景 のドキュメントを生成します。
興味深いことに、chucknorri
は同様に赤の背景を生成しますが、chucknorr
は黄色の背景を生成します。
いったい何が起こっているのでしょうか?
これはNetscape時代の名残です。
欠落した数字は0[...]として扱われます。例えば、#F0F0F0, F0F0F0, F0F0F, #FxFxFx, FxFxFxは全て同じ値です。
これは、ブログ記事 A little rant about Microsoft Internet Explorer's color parsing からの引用で、色の値の長さの違いなど、非常に詳細に説明されています。
このブログ記事から順番にルールを適用していくと、以下のようになります。
1.有効でない16進文字をすべて0に置き換える
chucknorrisはc00c0000000になります。
2.3で割り切れる次の総文字数までパッドアウトする(11→12)。
C00C 0000 0000
3.3等分して、それぞれの成分がRGBカラーの対応する色成分を表すようにする。
RGB (c00c, 0000, 0000)
4.右からの各引数を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"
とすれば、茶色になると指摘したときに、この現象に遭遇しました。
ほとんどのブラウザは、色の文字列に含まれるNON-HEXの値を単純に無視し、NON-HEXの数字をゼロで置き換えます。
ChuCknorris」は「c00c0000000」に変換されます。 この時点で、ブラウザは文字列を3つの等しいセクションに分割し、赤、緑、青の値を示します。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>
<! -- end snippet -->
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ビットの整数に収まる16進数は8桁だけなので、最後の8文字だけが考慮されるわけです。16進数を32ビット整数に解析した後、8ビットに収まるまで16で割って8ビット整数に切り詰めますが、このため先頭のゼロは無視されます。
Update: このコードは仕様書で定義されているものと完全には一致しませんが、そこでの違いは数行のコードだけです。ネットスケープ4で)追加されたのはこの行だと思います。
if (bytes_per_val > 4)
{
bytes_per_val = 4;
}