HTML neden "chucknorris "in bir renk olduğunu düşünüyor?

HTML'de arka plan rengi olarak girildiğinde nasıl oluyor da bazı rastgele dizeler renk üretiyor? Örneğin:

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

...tüm tarayıcılarda ve platformlarda kırmızı arka plana sahip bir belge üretir.

İlginç bir şekilde, chucknorri de kırmızı bir arka plan üretirken, chucknorr sarı bir arka plan üretir.

Burada neler oluyor?

Çözüm

Netscape günlerinden kalma bir şey:

Eksik rakamlar 0 olarak değerlendirilir[...]. Yanlış bir rakam basitçe 0 olarak yorumlanır. Örneğin #F0F0F0, F0F0F0, F0F0F, #FxFxFx ve FxFxFx değerlerinin hepsi aynıdır.

Bu yazı Microsoft Internet Explorer'ın renk ayrıştırması hakkında küçük bir rant blog yazısından alınmıştır ve renk değerlerinin değişen uzunlukları vb. dahil olmak üzere konuyu ayrıntılı olarak ele almaktadır.

Blog yazısındaki kuralları sırayla uygularsak, aşağıdakileri elde ederiz:

  1. Geçerli olmayan tüm onaltılık karakterleri 0'larla değiştirin

    chucknorris c00c0000000 oldu
  2. 3'e bölünebilen bir sonraki toplam karakter sayısına kadar tamponlayın (11 -> 12)

    c00c 0000 0000
  3. Her bir bileşen bir RGB renginin karşılık gelen renk bileşenini temsil edecek şekilde üç eşit gruba bölün:

    RGB (c00c, 0000, 0000)
  4. Argümanların her birini sağdan iki karaktere kadar kısaltın

Bu da aşağıdaki sonucu verir:

RGB (c0, 00, 00) = #C00000 or RGB(192, 0, 0)

İşte bu "şaşırtıcı" renk örneğini üretmek için `bgcolor' niteliğini iş başında gösteren bir örnek:

<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>

Bu aynı zamanda sorunun diğer kısmını da yanıtlıyor; bgcolor="chucknorr" neden sarı bir renk üretiyor? Eğer kuralları uygularsak, dize şöyle olur:

c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]

Bu da açık sarı altın rengini verir. Dize 9 karakter olarak başladığından, bu sefer ikinci C'yi tutuyoruz, dolayısıyla nihai renk değerine ulaşıyor.

Bu durumla ilk olarak birisi color="crap" yapabileceğinizi ve kahverengi çıkacağını söylediğinde karşılaşmıştım.

Yorumlar (15)

Çoğu tarayıcı, renk dizenizdeki hex olmayan değerleri yok sayar ve hex olmayan rakamları sıfırlarla değiştirir.

ChuCknorris, c00c0000000 anlamına gelir. Bu noktada, tarayıcı dizeyi Kırmızı, Yeşil ve Mavi değerlerini gösteren üç eşit bölüme ayıracaktır: c00c 0000 0000. Her bölümdeki fazladan bitler göz ardı edilir, bu da nihai sonucu kırmızımsı bir renk olan #c00000 yapar.

Not, bu CSS standardını takip eden CSS renk ayrıştırması için * geçerli değildir.

<p>Redish</p>
<p>Same as above</p>
<p><span style="color: chucknorris">Black</span></p>
Yorumlar (4)

WHATWG HTML spesifikasyonu, eski bir renk değerini ayrıştırmak için tam algoritmaya sahiptir: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

Netscape Classic'in renk dizelerini ayrıştırmak için kullandığı kod açık kaynak kodludur: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

Örneğin, her karakterin bir hex rakamı olarak ayrıştırıldığına ve ardından taşma kontrolü yapılmadan 32 bitlik bir tamsayıya kaydırıldığına dikkat edin. Yalnızca sekiz onaltılık basamak 32 bitlik bir tamsayıya sığar, bu nedenle yalnızca son 8 karakter dikkate alınır. Onaltılı rakamlar 32 bitlik tamsayılara ayrıştırıldıktan sonra, 8 bite sığana kadar 16'ya bölünerek 8 bitlik tamsayılara kesilir, bu nedenle baştaki sıfırlar göz ardı edilir.

Güncelleme: bu kod spesifikasyonda tanımlananla tam olarak eşleşmiyor, ancak aradaki tek fark birkaç satır kod. Sanırım (Netscape 4'te) eklenen bu satırlardı:

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