Hvorfor tror HTML at "chucknorris" er en farge?

Hvorfor produserer visse tilfeldige strenger farger når de legges inn som bakgrunnsfarger i HTML? For eksempel

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

...produserer et dokument med rød bakgrunn på tvers av alle nettlesere og plattformer.

Interessant nok produserer chucknorri også en rød bakgrunn, mens chucknorr produserer en gul bakgrunn.

Hva er det som skjer her?

Løsning

Det er en etterlevning fra Netscape-tiden:

Manglende sifre behandles som 0[...]. Et feil siffer tolkes ganske enkelt som 0. For eksempel er verdiene #F0F0F0, F0F0F0, F0F0F, #FxFxFx og FxFxFx like.

Det er fra blogginnlegget A little rant about Microsoft Internet Explorer&# 39s color parsing som dekker det i detalj, inkludert varierende lengder på fargeverdier osv.

Hvis vi bruker reglene etter tur fra blogginnlegget, får vi følgende:

  1. Erstatt alle ikke-gyldige heksadesimale tegn med 0' s

    chucknorris blir c00c0000000
  2. Fyll ut til neste totale antall tegn som er delelig med 3 (11 - > 12)

    c00c 0000 0000
  3. Deles inn i tre like store grupper, der hver komponent representerer den tilsvarende fargekomponenten i en RGB-farge:

    RGB (c00c, 0000, 0000).
  4. Avkort hvert av argumentene fra høyre ned til to tegn.

Som gir følgende resultat:

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

Her er et eksempel som demonstrerer bgcolor-attributtet i aksjon, for å produsere denne " fantastiske " fargeprøven:

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

Dette svarer også på den andre delen av spørsmålet; hvorfor produserer bgcolor="chucknorr" en gul farge? Vel, hvis vi bruker reglene, er strengen:

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

Som gir en lys gul gullfarge. Ettersom strengen starter med 9 tegn, beholder vi den andre C-en denne gangen, slik at den ender opp i den endelige fargeverdien.

Jeg møtte opprinnelig dette da noen påpekte at du kunne gjøre `color="crap" og, vel, det kommer ut brunt.

Kommentarer (15)

De fleste nettlesere vil ganske enkelt ignorere alle IKKE-hex-verdier i fargestrengen din, og erstatte ikke-hex-sifre med nuller.

ChuCknorris oversettes til c00c0000000. På dette tidspunktet vil nettleseren dele strengen inn i tre like deler, som angir verdiene Rød, Grønn og Blå: c00c 0000 0000. Ekstra biter i hver seksjon vil bli ignorert, slik at sluttresultatet blir #c00000, som er en rødlig farge.

Merk at dette ikke gjelder for CSS-fargeanalyse, som følger CSS-standarden.

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

WHATWG HTML-spesifikasjonen har den nøyaktige algoritmen for å analysere en eldre fargeverdi: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

Netscape Classic-koden som brukes til å analysere fargestrenger, er åpen kildekode: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

Legg for eksempel merke til at hvert tegn analyseres som et heksesiffer og deretter flyttes til et 32-bits heltall uten å sjekke for overløp. Bare åtte heksesifre får plass i et 32-bits heltall, og det er derfor bare de siste 8 tegnene som tas i betraktning. Etter å ha analysert heksesifrene til 32-bits heltall, blir de deretter trunkert til 8-bits heltall ved å dele dem på 16 til de passer inn i 8-bits, noe som er grunnen til at foranstilte nuller ignoreres.

Oppdatering: denne koden samsvarer ikke nøyaktig med det som er definert i spesifikasjonen, men den eneste forskjellen er noen få linjer med kode. Jeg tror det er disse linjene som ble lagt til (i Netscape 4):

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