it-swarm.com.de

Warum hält HTML „chucknorris“ für eine Farbe?

Wie kommt es, dass bestimmte zufällige Zeichenfolgen Farben erzeugen, wenn sie in HTML als Hintergrundfarben eingegeben werden? Zum Beispiel:

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

... erstellt ein Dokument mit einem roter Hintergrund in allen Browsern und Plattformen.

Während chucknorri ebenfalls einen roten Hintergrund erzeugt, erzeugt chucknorr interessanterweise einen gelben Hintergrund.

Was ist hier los?

7142
user456584

Es ist ein Überbleibsel aus den Netscape-Tagen:

Fehlende Ziffern werden als 0 [...] behandelt. Eine falsche Ziffer wird einfach als 0 interpretiert. Zum Beispiel sind die Werte # F0F0F0, F0F0F0, F0F0F, #FxFxFx und FxFxFx alle gleich.

Es ist aus dem Blog-Beitrag Ein wenig über die Farbanalyse von Microsoft Internet Explorer gestritten, der es ausführlich behandelt, einschließlich unterschiedlicher Längen von Farbwerten usw.

Wenn wir die Regeln der Reihe nach aus dem Blog-Post übernehmen, erhalten wir Folgendes:

  1. Ersetzen Sie alle nicht gültigen Hexadezimalzeichen durch Nullen

    chucknorris becomes c00c0000000
    
  2. Auf die nächste Gesamtzahl der durch 3 teilbaren Zeichen auffüllen (11 -> 12)

    c00c 0000 0000
    
  3. In drei gleiche Gruppen aufgeteilt, wobei jede Komponente die entsprechende Farbkomponente einer RGB-Farbe darstellt:

    RGB (c00c, 0000, 0000)
    
  4. Kürzen Sie jedes der Argumente von rechts nach unten auf zwei Zeichen

Was das folgende Ergebnis ergibt:

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

Hier ist ein Beispiel, das das bgcolor -Attribut in Aktion demonstriert, um dieses "erstaunliche" Farbmuster zu erzeugen:

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

Dies beantwortet auch den anderen Teil der Frage; Warum erzeugt bgcolor="chucknorr" eine gelbe Farbe? Nun, wenn wir die Regeln anwenden, lautet die Zeichenfolge:

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

Das ergibt eine hellgelbe Goldfarbe. Da die Zeichenfolge mit 9 Zeichen beginnt, wird das zweite C dieses Mal beibehalten, sodass es im endgültigen Farbwert endet.

Ich bin ursprünglich darauf gestoßen, als jemand darauf hingewiesen hat, dass Sie color="crap" ausführen können, und nun, es kommt braun heraus.

6585
dash

Es tut mir leid, dass ich nicht damit einverstanden bin, aber gemäß den Regeln zum Parsen eines von @ Yuhong Bao geposteten Legacy-Farbwerts entspricht chucknorris NICHT #CC0000, sondern #C00000, eine sehr ähnliche, aber leicht abweichende rote Farbe. Ich habe das Firefox ColorZilla Add-On verwendet, um dies zu überprüfen.

Die Regeln besagen:

  • machen Sie die Zeichenfolge zu einer Länge, die ein Vielfaches von 3 ist, indem Sie 0s hinzufügen: chucknorris0
  • trenne die Zeichenkette in 3 gleichlange Zeichenketten: chuc knor ris0
  • schneide jede Zeichenfolge auf 2 Zeichen ab: ch kn ri
  • behalten Sie die hexadezimalen Werte bei und addieren Sie gegebenenfalls die Nullen: C0 00 00

Ich konnte diese Regeln verwenden, um die folgenden Zeichenfolgen korrekt zu interpretieren:

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle

UPDATE: Die ursprünglichen Antwortenden, die sagten, dass die Farbe #CC0000 war, haben ihre Antworten seitdem bearbeitet, um die Korrektur einzuschließen.

914
Jeremy Goodell

Die meisten Browser ignorieren einfach alle Nicht-Hex-Werte in Ihrer Farbzeichenfolge und ersetzen Nicht-Hex-Ziffern durch Nullen.

ChuCknorris übersetzt in c00c0000000. Zu diesem Zeitpunkt teilt der Browser die Zeichenfolge in drei gleiche Abschnitte auf, die die Werte Rot, Grün und Bla angeben: c00c 0000 0000. Zusätzliche Bits in jedem Abschnitt werden ignoriert, wodurch das Endergebnis #c00000 eine rötliche Farbe erhält.

Beachten Sie, dass dies nicht für die CSS-Farbanalyse gilt, die dem CSS-Standard folgt.

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

Der Browser versucht, chucknorris in hexadezimalen Farbcode umzuwandeln, da es sich nicht um einen gültigen Wert handelt.

  1. In chucknorris ist alles außer c kein gültiger hexadezimaler Wert.
  2. Also wird es in c00c00000000 konvertiert.
  3. Welches wird # c000, eine Nuance von Rot.

Dies scheint vor allem bei Internet Explorer und Opera (12) ein Problem zu sein, da sowohl Chrome (31) als auch Firefox (26) dies einfach ignorieren.

P.S. Die Zahlen in Klammern sind die Browserversionen, auf denen ich getestet habe.

.

Leichter gesagt

Chuck Norris entspricht nicht den Webstandards. Webstandards entsprechen ihm. # BADA55

276
aWebDeveloper

Der Grund ist, dass der Browser es nicht verstehen kann und versucht, es irgendwie in das zu übersetzen, was er verstehen kann und in diesem Fall in einen hexadezimalen Wert! ...

chucknorris beginnt mit c, das als Hexadezimalzeichen erkannt wird. Außerdem werden alle nicht erkannten Zeichen in 0 konvertiert.

So wird chucknorris im hexadezimalen Format zu: c00c00000000, alle anderen Zeichen werden 0 und c verbleiben dort, wo sie sich befinden ...

Jetzt werden sie durch 3 geteilt für RGB (rot, grün, blau) ... R: c00c, G: 0000, B:0000...

Wir wissen jedoch, dass eine gültige Hexadezimalzahl für RGB nur 2 Zeichen beträgt, dh R: c0, G: 00, B:00.

Das eigentliche Ergebnis ist also:

bgcolor="#c00000";

Ich habe auch die Schritte im Bild als Kurzreferenz für Sie hinzugefügt:

Why does HTML think “chucknorris” is a color?

235
Alireza

Die WHATWG-HTML-Spezifikation enthält den genauen Algorithmus zum Parsen eines älteren Farbwerts: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

Der zum Parsen von Farbzeichenfolgen verwendete Code Netscape Classic ist Open Source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

Beachten Sie beispielsweise, dass jedes Zeichen als Hexadezimalzahl analysiert und dann in eine 32-Bit-Ganzzahl verschoben wird, ohne auf Überlauf zu prüfen . In eine 32-Bit-Ganzzahl passen nur acht Hexadezimalziffern, weshalb nur die letzten 8 Zeichen berücksichtigt werden. Nach dem Parsen der Hexadezimalziffern in 32-Bit-Ganzzahlen werden diese durch Teilen durch 16 in 8-Bit-Ganzzahlen gekürzt, bis sie in 8-Bit passen. Deshalb werden führende Nullen ignoriert.

Update: Dieser Code stimmt nicht genau mit der Definition in der Spezifikation überein, aber der einzige Unterschied sind einige Codezeilen. Ich denke, es sind diese Zeilen, die hinzugefügt wurden (in Netscape 4):

if (bytes_per_val > 4)
{
      bytes_per_val = 4;
}
207
Yuhong Bao

Antwort:

  • Der Browser versucht, chucknorris in einen Hexadezimalwert umzuwandeln.
  • Da c das einzige gültige Hex-Zeichen in chucknorris ist, wird der Wert zu: c00c00000000 (für alle ungültigen Werte).
  • Der Browser unterteilt das Ergebnis dann in 3 Gruppen: Red = c00c, Green = 0000, Blue = 0000.
  • Da gültige Hexadezimalwerte für HTML-Hintergründe nur 2 Ziffern für jeden Farbtyp enthalten (r, g, b), werden die letzten 2 Ziffern abgeschnitten aus jeder Gruppe, wobei ein RGB-Wert von c00000 übrig bleibt, der eine ziegelrötlich getönte Farbe ist.
189
Webeng

chucknorris beginnt mit c und wird vom Browser hexadezimal gelesen .

Weil A, B, C, D, E und F hexadezimale Zeichen sind.

Der Browser konvertiert chucknorris in einen hexadezimalen Wert, C00C00000000.

Dann wird der Hexadezimalwert C00C00000000 in das Format RGB konvertiert (geteilt durch 3):

C00C00000000 => R:C00C, G:0000, B:0000

Der Browser benötigt nur zwei Ziffern, um die Farbe anzuzeigen:

R:C00C, G:0000, B:0000 => R:C0, G:00, B:00 => C00000

Zeigen Sie abschließend im Webbrowser bgcolor = C00000 an.

Hier ist ein Beispiel, das dies demonstriert:

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

Das Regeln für das Parsen von Farben in Legacy-Attributen umfasst zusätzliche Schritte als die in vorhandenen Antworten genannten. Der Anteil der Kürzung auf 2 Stellen wird wie folgt beschrieben:

  1. Verwerfen Sie alle Zeichen mit Ausnahme der letzten 8
  2. Verwerfen Sie führende Nullen nacheinander , solange alle Komponenten eine führende Null haben
  3. Verwerfen Sie alle Zeichen außer den ersten 2

Einige Beispiele:

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

Unten sehen Sie eine teilweise Implementierung des Algorithmus. Es behandelt keine Fehler oder Fälle, in denen der Benutzer eine gültige Farbe eingibt.

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>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
  </tbody>
</table>
7
Salman A