web-dev-qa-db-fra.com

Pourquoi HTML pense-t-il que «chucknorris» est une couleur?

Comment se fait-il que certaines chaînes aléatoires produisent des couleurs lorsqu'elles sont entrées en tant que couleurs d'arrière-plan en HTML? Par exemple:

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

... produit un document avec un arrière-plan rouge sur tous les navigateurs et toutes les plateformes.

Fait intéressant, bien que chucknorri produise également un arrière-plan rouge, chucknorr génère un arrière-plan jaune.

Que se passe t-il ici?

7142
user456584

C'est une retenue de l'époque de Netscape:

Les chiffres manquants sont traités comme 0 [...]. Un chiffre incorrect est simplement interprété comme 0. Par exemple, les valeurs # F0F0F0, F0F0F0, F0F0F, #FxFxFx et FxFxFx sont toutes identiques.

C'est tiré de l'article de blog n petit discours sur l'analyse de la couleur de Microsoft Internet Explorer qui le traite en détail, y compris les longueurs variables des valeurs de couleur, etc.

Si nous appliquons les règles à partir de la publication de blog, nous obtenons ce qui suit:

  1. Remplacer tous les caractères hexadécimaux non valides par des 0

    chucknorris becomes c00c0000000
    
  2. Pavé au prochain nombre total de caractères divisibles par 3 (11 -> 12)

    c00c 0000 0000
    
  3. Divisé en trois groupes égaux, chaque composant représentant le composant de couleur correspondant à une couleur RVB:

    RGB (c00c, 0000, 0000)
    
  4. Tronquer chacun des arguments de la droite vers le bas à deux caractères

Ce qui donne le résultat suivant:

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

Voici un exemple démontrant l'attribut bgcolor en action pour produire cette nuance de couleurs "étonnante":

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

Cela répond également à l'autre partie de la question. pourquoi bgcolor="chucknorr" produit-il une couleur jaune? Eh bien, si nous appliquons les règles, la chaîne est la suivante:

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

Ce qui donne une couleur or jaune clair. Comme la chaîne commence par 9 caractères, nous conservons le deuxième C cette fois-ci et finissons donc dans la valeur de couleur finale.

Je l’ai rencontré à l’origine lorsque quelqu'un a fait remarquer que vous pouviez faire color="crap" et, eh bien, le résultat est brun.

6585
dash

Je suis désolé de ne pas être d’accord, mais selon les règles pour analyser une valeur de couleur héritée postée par @ Yuhong Bao , chucknorris n’équivalent pas à #CC0000, mais plutôt à #C00000, une teinte de rouge très similaire mais légèrement différente. J'ai utilisé le Firefox ColorZilla add-on pour le vérifier.

Les règles stipulent:

  • donnez à la chaîne une longueur multiple de 3 en ajoutant des 0: chucknorris0
  • séparez la chaîne en 3 chaînes égales: chuc knor ris0
  • tronquer chaque chaîne à 2 caractères: ch kn ri
  • conservez les valeurs hexadécimales et ajoutez des zéros si nécessaire: C0 00 00

J'ai pu utiliser ces règles pour interpréter correctement les chaînes suivantes:

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle

UPDATE: Les répondants ayant déclaré que la couleur était #CC0000 ont depuis modifié leurs réponses pour inclure la correction.

914
Jeremy Goodell

La plupart des navigateurs ignorent simplement les valeurs non hexadécimales de votre chaîne de couleur, en remplaçant les chiffres non hexadécimaux par des zéros.

ChuCknorris se traduit par c00c0000000. À ce stade, le navigateur divisera la chaîne en trois sections égales, en indiquant rouge , vert et Valeurs bleues : c00c 0000 0000. Les bits supplémentaires dans chaque section seront ignorés, ce qui donne le résultat final #c00000 qui est de couleur rougeâtre.

Notez que cela ne s'applique pas à l'analyse des couleurs CSS, qui est conforme à la norme 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>
369
Mike Christensen

Le navigateur tente de convertir chucknorris en code de couleur hexadécimal, car cette valeur n'est pas valide.

  1. Dans chucknorris, tout sauf c n'est pas une valeur hexadécimale valide.
  2. Donc, il est converti en c00c00000000.
  3. Ce qui devient # c000, une nuance de rouge.

Cela semble être un problème principalement avec Internet Explorer et Opera (12), étant donné que Chrome (31) et Firefox (26) l'ignorent.

P.S. Les nombres entre parenthèses sont les versions de navigateur sur lesquels j'ai testé.

.

Sur une note plus légère

Chuck Norris n'est pas conforme aux normes Web. Les normes Web lui sont conformes. # BADA55

276
aWebDeveloper

La raison en est que le navigateur peut ne pas comprendre et essayer de le traduire d'une manière ou d'une autre en ce qu'il peut comprendre et dans ce cas en une valeur hexadécimale! ...

chucknorris commence par c qui est un caractère reconnu en hexadécimal et convertit également tous les caractères non reconnus en 0!

Ainsi, chucknorris au format hexadécimal devient: c00c00000000, tous les autres caractères deviennent 0 et c restent à leur place ...

Maintenant, ils sont divisés par 3 pour RGB (rouge, vert, bleu) ... R: c00c, G: 0000, B:0000...

Mais nous savons que l'hexadécimal valide pour le RVB ne contient que 2 caractères, ce qui signifie R: c0, G: 00, B:00

Le résultat réel est donc:

bgcolor="#c00000";

J'ai également ajouté les étapes dans l'image comme référence rapide pour vous:

Why does HTML think “chucknorris” is a color?

235
Alireza

La spécification HTML de WHATWG a l'algorithme exact pour l'analyse d'une valeur de couleur héritée: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

Le code utilisé par Netscape Classic pour analyser les chaînes de couleur est open source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

Par exemple, notez que chaque caractère est analysé comme un chiffre hexadécimal, puis décalé dans un entier 32 bits sans vérification du débordement . Seuls huit chiffres hexadécimaux entrent dans un entier de 32 bits, ce qui explique pourquoi seuls les 8 derniers caractères sont pris en compte. Après avoir analysé les chiffres hexadécimaux en nombres entiers de 32 bits, ils sont ensuite tronqués en nombres de 8 bits en les divisant par 16 jusqu'à ce qu'ils entrent en 8 bits, ce qui explique pourquoi les zéros en tête sont ignorés.

Mise à jour: ce code ne correspond pas exactement à ce qui est défini dans la spécification, mais la seule différence est qu'il existe quelques lignes de code. Je pense que ce sont ces lignes qui ont été ajoutées (dans Netscape 4):

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

Réponse:

  • Le navigateur essaiera de convertir chucknorris en une valeur hexadécimale.
  • Puisque c est le seul caractère hexadécimal valide de chucknorris, la valeur devient: c00c00000000 (pour toutes les valeurs non valides).
  • Le navigateur divise ensuite le résultat en 3 groupes: Red = c00c, Green = 0000, Blue = 0000.
  • Puisque les valeurs hexadécimales valides pour les arrière-plans html ne contiennent que 2 chiffres pour chaque type de couleur (r, g, b), les 2 derniers chiffres sont tronqués. de chaque groupe, en laissant une valeur de rgb de c00000 qui est une couleur rouge brique.
189
Webeng

chucknorris commence par c , et le navigateur le lit sous forme de valeur hexadécimale .

Parce que A, B, C, D, E et F sont caractères en hexadécimal .

Le navigateur convertit chucknorris en une valeur hexadécimale, C00C00000000.

Ensuite, la valeur hexadécimale C00C00000000 est convertie au format RGB (divisé par 3):

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

Le navigateur n'a besoin que de deux chiffres pour indiquer la couleur:

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

Enfin, affichez bgcolor = C00000 dans le navigateur Web.

Voici un exemple pour le démontrer:

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

Le règles pour l'analyse des couleurs sur les attributs hérités implique des étapes supplémentaires par rapport à celles mentionnées dans les réponses existantes. Le composant tronqué à la partie à 2 chiffres est décrit comme suit:

  1. Jeter tous les caractères sauf les 8 derniers
  2. Supprimez les zéros à gauche un par un tant que tous les composants ont un zéro non significatif
  3. Jeter tous les personnages sauf les 2 premiers

Quelques exemples:

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

Vous trouverez ci-dessous une implémentation partielle de l'algorithme. Il ne gère pas les erreurs ou les cas où l'utilisateur entre une couleur valide.

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