Vraag Waarom denkt HTML dat 'chucknorris' een kleur is?


Hoe komt het dat bepaalde willekeurige reeksen kleuren produceren als ze worden ingevoerd als achtergrondkleuren in HTML? Bijvoorbeeld:

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

... produceert een document met een rode achtergrond in alle browsers en platforms.

Interessant, terwijl chucknorri produceert ook een rode achtergrond, chucknorr produceert een gele achtergrond.

Wat gebeurd er hier?


6540
2017-11-29 22:54


oorsprong


antwoorden:


Het is een overblijfsel uit de Netscape-dagen:

Ontbrekende cijfers worden behandeld als 0 [...]. Een onjuist cijfer wordt eenvoudig geïnterpreteerd als 0. De waarden # F0F0F0, F0F0F0, F0F0F, #FxFxFx en FxFxFx zijn bijvoorbeeld allemaal hetzelfde.

Het is van de blogpost Een beetje rant over de kleuranalyse van Microsoft Internet Explorer die deze tot in detail afdekt, inclusief verschillende lengten van kleurwaarden, enz.

Als we de regels beurtelings toepassen vanuit de blogpost, krijgen we het volgende:

  1. Vervang alle niet-valide hexadecimale tekens door 0-en

    chucknorris becomes c00c0000000
    
  2. Pad naar het volgende totale aantal karakters deelbaar door 3 (11 -> 12)

    c00c 0000 0000
    
  3. Verdeeld in drie gelijke groepen, waarbij elke component de overeenkomstige kleurcomponent van een RGB-kleur vertegenwoordigt:

    RGB (c00c, 0000, 0000)
    
  4. Trots elk van de argumenten van maximaal twee tekens af

Wat het volgende resultaat geeft:

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

Hier is een voorbeeld van de demonstratie van bgcolor attribuut in actie om dit "geweldige" kleurstaal te produceren:

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

Dit beantwoordt ook het andere deel van de vraag; waarom doet bgcolor="chucknorr" een gele kleur produceren? Welnu, als we de regels toepassen, is de string:

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

Dat geeft een lichtgele gouden kleur. Omdat de string begint als 9 karakters, houden we deze keer de tweede C vast, vandaar dat deze eindigt in de uiteindelijke kleurwaarde.

Ik kwam dit oorspronkelijk tegen toen iemand erop wees dat je het kon doen color="crap" en goed, het komt bruin uit.


6041
2017-11-30 21:53



Het spijt me dat ik het niet eens ben, maar volgens de regels voor het parseren van een oude kleurwaarde die is gepost door @Yuhong Bao, chucknorris IS NIET gelijk aan #CC0000, maar eerder om #C00000, een zeer vergelijkbare maar licht verschillende tint rood. Ik gebruikte de Firefox ColorZilla-add-on om dit te verifiëren.

De regels vermelden:

  • maak de string een lengte die een veelvoud is van 3 door 0s toe te voegen: chucknorris0
  • scheid de reeks in 3 snaren van gelijke lengte: chuc knor ris0
  • truncate elke reeks tot 2 karakters: ch kn ri
  • bewaar de hex-waarden en voeg waar nodig 0's toe: C0 00 00

Ik kon deze regels gebruiken om de volgende strings correct te interpreteren:

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle 

BIJWERKEN: De originele antwoordapparaten die zeiden dat de kleur was #CC0000 hebben sindsdien hun antwoorden bewerkt om de correctie op te nemen.


826
2017-10-17 17:55



De meeste browsers negeren eenvoudig alle niet-hexwaarden in uw kleurstring en vervangen door niet-hexadecimale cijfers met nullen.

ChuCknorris vertaald naar c00c0000000. Op dit punt deelt de browser de reeks in drie gelijke secties, wat aangeeft Rood, Groen en Blauw waarden: c00c 0000 0000. Extra bits in elke sectie worden genegeerd, wat het eindresultaat oplevert #c00000 welke een roodachtige kleur heeft.

Let op, dit doet niet van toepassing op CSS-kleurparsen, volgens de CSS-standaard.

<p><font color='chucknorris'>Redish</font></p>
<p><font color='#c00000'>Same as above</font></p>
<p><span style="color: chucknorris">Black</span></p>


337
2017-11-29 23:01



De browser probeert te converteren chucknorris in hex kleurcode, omdat het geen geldige waarde is.

  1. In chucknorrisalles behalve c is geen geldige hex-waarde.
  2. Dus het wordt omgezet naar c00c00000000.
  3. Welke wordt # c00000, een schaduw van rood.

Dit lijkt vooral een probleem te zijn internet Explorer en Opera (12) omdat zowel Chrome (31) als Firefox (26) dit gewoon negeren.

Postscriptum De cijfers tussen haakjes zijn de browserversies waarop ik heb getest.

.

Op een lichtere toon

Chuck Norris voldoet niet aan webstandaarden. Webstandaarden conform   naar hem. # BADA55


219
2017-11-30 14:05



De WHATWG HTML-specificatie heeft het exacte algoritme voor het parseren van een oude kleurwaarde: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

De code die Netscape Classic gebruikt voor het parseren van kleurstrings is open source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

Merk bijvoorbeeld op dat elk teken wordt ontleed als een hexadecimaal cijfer en vervolgens wordt verschoven naar een 32-bits geheel getal zonder te controleren op overloop. Slechts acht hex-cijfers passen in een 32-bits geheel getal, daarom worden alleen de laatste 8 tekens beschouwd. Na het ontleden van de hexadecimale getallen in 32-bits gehele getallen, worden ze vervolgens ingekort tot 8-bits gehele getallen door ze te delen door 16 totdat ze in 8-bits passen, wat de reden is dat voorloopnullen worden genegeerd.

Update: deze code komt niet exact overeen met wat in de specificatie is gedefinieerd, maar het enige verschil is dat er een paar regels code zijn. Ik denk dat het deze lijnen zijn die werden toegevoegd (in Netscape 4):

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

186
2017-09-27 22:01



Antwoord: 

  • De browser zal proberen te converteren ChuckNorris in een hexadecimale waarde.
  • Sinds c is het enige geldige hexadecimale teken in ChuckNorris, de waarde wordt: c00c00000000(0 voor alle waarden die ongeldig waren).
  • De browser verdeelt het resultaat vervolgens in 3 groepen: Red = c00c, Green = 0000, Blue = 0000.
  • Omdat geldige hex-waarden voor html-achtergronden slechts 2 cijfers bevatten voor elk kleurtype (r, g, b), worden de laatste 2 cijfers ingekort van elke groep, waardoor een rgb-waarde van c00000 welke een baksteen-roodachtige getinte kleur heeft.

166
2018-05-24 05:18



De reden is de browser kan begrijp niet het en probeer het op de een of andere manier te vertalen naar wat het kan begrijpen en in dit geval naar een hexadecimale waarde!

chucknorris begint met c wat een herkend teken in hexadecimaal is, het converteert ook alle niet-herkende tekens naar 0!

Zo chucknorris in hexadecimaal formaat wordt: c00c00000000, alle andere karakters worden 0 en c blijft waar ze zijn ...

Nu worden ze gedeeld door 3 voor RGB(rood, groen, blauw) ... R: c00c, G: 0000, B:0000...

Maar we weten dat geldig hexadecimaal voor RGB slechts 2 tekens betekent R: c0, G: 00, B:00

Dus het echte resultaat is:

bgcolor="#c00000";

Ik heb ook de stappen in de afbeelding toegevoegd als een snel overzicht:

Why does HTML think “chucknorris” is a color?


133
2017-07-01 04:08