Почему HTML считает "chucknorris" цветом?

Почему некоторые случайные строки создают цвета, когда вводятся в качестве фоновых цветов в HTML? Например:

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

Ответ 1

Это пережиток дней Netscape:

Недостающие цифры рассматриваются как 0 [...]. Неправильная цифра просто интерпретируется как 0. Например, значения # F0F0F0, F0F0F0, F0F0F, #FxFxFx и FxFxFx являются одинаковыми.

Это из поста в блоге Немного рассуждаю о разборе цвета в Microsoft Internet Explorer, который подробно описывает его, в том числе различную длину значений цвета и т.д.

Если мы применяем правила по очереди из поста в блоге, мы получаем следующее:

  1. Заменить все недействительные шестнадцатеричные символы на 0

    chucknorris becomes c00c0000000
    
  2. Заполните до следующего общего количества символов, делимых на 3 (11 → 12)

    c00c 0000 0000
    
  3. Разделить на три равные группы, где каждый компонент представляет соответствующий компонент цвета цвета RGB:

    RGB (c00c, 0000, 0000)
    
  4. Обрезать каждый из аргументов справа вниз до двух символов

Что дает следующий результат:

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

Вот пример, демонстрирующий атрибут bgcolor в действии, чтобы создать этот "удивительный" образец цвета:

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

Ответ 2

Извините, что не согласен, но согласно правилам парсинга устаревшего значения цвета, опубликованного @Yuhong Bao, chucknorris НЕ приравнивается к #CC0000, а скорее к #C00000, очень похожему, но немного отличающемуся оттенку красного. Я использовал дополнение Firefox ColorZilla, чтобы проверить это.

Правила гласят:

  • сделайте строку длиной, кратной 3, добавив 0s: chucknorris0
  • разделите строку на 3 строки одинаковой длины: chuc knor ris0
  • обрезать каждую строку до 2 символов: ch kn ri
  • оставьте шестнадцатеричные значения и, если необходимо, добавьте 0: C0 00 00

Я смог использовать эти правила для правильной интерпретации следующих строк:

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle

ОБНОВЛЕНИЕ: оригинальные ответчики, которые сказали, что цвет был #CC0000, с тех пор отредактировали свои ответы, чтобы включить исправление.

Ответ 3

Большинство браузеров просто игнорируют любые не шестнадцатеричные значения в вашей цветовой строке, заменяя не шестнадцатеричные цифры нулями.

ChuCknorris переводится как c00c0000000. На этом этапе браузер разделит строку на три равные части, указав значения красного, зеленого и синего: c00c 0000 0000. Лишние биты в каждом разделе будут игнорироваться, в результате чего конечный результат #c00000 будет красноватого цвета.

Обратите внимание, что это не относится к анализу цвета CSS, который соответствует стандарту 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>

Ответ 4

Браузер пытается преобразовать chucknorris в шестнадцатеричный цветовой код, потому что это недопустимое значение.

  1. В chucknorris все, кроме c, не является допустимым шестнадцатеричным значением.
  2. Таким образом, он конвертируется в c00c00000000.
  3. Которая становится # c00000, оттенок красного.

Похоже, что это проблема в первую очередь для Internet Explorer и Opera (12), так как Chrome (31) и Firefox (26) просто игнорируют это.

PS Цифры в скобках - это версии браузера, на которых я тестировал.

,

На более легкой ноте

Чак Норрис не соответствует веб-стандартам. Веб-стандарты соответствуют ему. # BADA55

Ответ 5

Причина в том, что браузер не может понять это и пытается каким-то образом перевести это в то, что он может понять, и в этом случае в шестнадцатеричное значение!...

chucknorris начинается с c который является распознаваемым символом в шестнадцатеричном формате, а также преобразует все нераспознанные символы в 0 !

Таким образом, chucknorris в шестнадцатеричном формате становится: c00c00000000, все остальные символы становятся 0 а c остается там, где они есть...

Теперь они делятся на 3 для RGB (красный, зеленый, синий)... R: c00c, G: 0000, B:0000...

Но мы знаем, что действительный шестнадцатеричный код для RGB - всего 2 символа, это означает, что R: c0, G: 00, B:00

Итак, реальный результат:

bgcolor="#c00000";

Я также добавил шаги на изображении в качестве краткого справочника для вас:

Почему HTML думает

Ответ 6

HTML-спецификация WHATWG имеет точный алгоритм анализа устаревшего значения цвета: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

Код Netscape Classic, используемый для разбора цветовых строк, имеет открытый исходный код: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155.

Например, обратите внимание, что каждый символ анализируется как шестнадцатеричное число, а затем сдвигается в 32-разрядное целое число без проверки на переполнение. Только восемь шестнадцатеричных цифр вписываются в 32-разрядное целое число, поэтому учитываются только последние 8 символов. После разбора шестнадцатеричных чисел на 32-разрядные целые числа они затем усекаются до 8-разрядных целых чисел, деля их на 16, пока они не вписываются в 8-разрядные, поэтому начальные нули игнорируются.

Обновление: этот код не совсем соответствует тому, что определено в спецификации, но единственное отличие - несколько строк кода. Я думаю, что эти строки были добавлены (в Netscape 4):

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

Ответ 7

Ответ:

  • Браузер попытается преобразовать chucknorris в шестнадцатеричное значение.
  • Поскольку c является единственным допустимым шестнадцатеричным символом в chucknorris, значение превращается в: c00c00000000 (0 для всех недопустимых значений).
  • Затем браузер делит результат на 3 группы: Red = c00c, Green = 0000, Blue = 0000.
  • Поскольку действительные шестнадцатеричные значения для фонов html содержат только 2 цифры для каждого типа цвета (r, g, b), последние 2 цифры усекаются из каждой группы, оставляя значение rgb c00000 которое является цветом кирпично-красного тона.

Ответ 8

chucknorris начинается с c, и браузер считывает его в шестнадцатеричное значение.

Потому что A, B, C, D, E и F - символы в шестнадцатеричном формате.

Браузер преобразует chucknorris в шестнадцатеричное значение C00C00000000.

Затем шестнадцатеричное значение C00C00000000 преобразуется в формат RGB (деленный на 3):

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

Браузеру нужны только две цифры для обозначения цвета:

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

Наконец, покажите bgcolor = C00000 в веб-браузере.

Вот пример, демонстрирующий это:

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

Ответ 9

Правила синтаксического анализа цветов унаследованных атрибутов включают в себя дополнительные шаги, чем те, которые упомянуты в существующих ответах. Компонент усечения до двухзначной части описывается как:

  1. Отменить все символы, кроме последних 8
  2. Сбрасывать начальные нули один за другим, если все компоненты имеют начальный ноль
  3. Отменить все символы, кроме первых 2

Некоторые примеры:

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

Ниже приведена частичная реализация алгоритма. Он не обрабатывает ошибки или случаи, когда пользователь вводит правильный цвет.

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>

Ответ 10

При разборе цветов недопустимые цифры рассматриваются как 0. Итак, chucknorris => c00c0000000 Это делится на 3 части (r, g, b). Итак, chucknorris => c00c 0000 000 Учитываются только первые две цифры. Итак, chucknorris => c0 00 00 А, RGB (c0, 00, 00) КРАСНЫЙ. Я думаю, вы можете понять, почему chucknorr => желтый сейчас.

Ответ 11

Точное значение шестнадцатеричного цвета не имеет значения. Знаете ли вы, что Чак Норрис изобрел черный цвет? На самом деле он изобрел весь спектр цветов..... кроме розового. Том Круз изобрел розовый.

Ответ 12

HTML распознает "Чак Норрис" как цветной код # C00000.

Ответ 13

Это потому, что "chucknorris" в шестнадцатеричном виде это всего лишь 255000000. Это эквивалентно приведенному ниже коду:

<p><font color='red'>Redish</font><p>