Почему HTML считает "chucknorris" цветом?
Почему некоторые случайные строки создают цвета, когда вводятся в качестве фоновых цветов в HTML? Например:
<body bgcolor="chucknorris"> test </body>
... создает документ с красным фоном во всех браузерах и платформах.
Интересно, а пока chucknorri
создает красный фон, chucknorr
производит желтый фон.
Что тут происходит?
12 ответов
Это пережиток дней Netscape:
Недостающие цифры рассматриваются как 0[...]. Неправильная цифра просто интерпретируется как 0. Например, значения #F0F0F0, F0F0F0, F0F0F, #FxFxFx и FxFxFx являются одинаковыми.
Это из поста в блоге . Немного рассуждаю о разборе цвета в Microsoft Internet Explorer, который подробно описывает его, в том числе различную длину значений цвета и т. Д.
Если мы применяем правила по очереди из поста в блоге, мы получаем следующее:
Заменить все недействительные шестнадцатеричные символы на 0
chucknorris becomes c00c0000000
Заполните до следующего общего количества символов, делимых на 3 (11 -> 12)
c00c 0000 0000
Разделить на три равные группы, где каждый компонент представляет соответствующий компонент цвета цвета RGB:
RGB (c00c, 0000, 0000)
Обрезать каждый из аргументов справа вниз до двух символов
Что дает следующий результат:
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>
Это также отвечает на другую часть вопроса; Почему bgcolor="chucknorr"
производить желтый цвет? Хорошо, если мы применяем правила, строка выглядит так:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]
Что дает светло-желтый цвет золота. Поскольку строка начинается с 9 символов, мы сохраняем второй символ C на этот раз, поэтому она заканчивается в конечном значении цвета.
Я изначально столкнулся с этим, когда кто-то указал, что вы могли бы сделать color="crap"
и, ну, это выходит коричневым.
Извините, что не согласен, но в соответствии с правилами парсинга устаревшего значения цвета, опубликованного @Yuhong Bao, chucknorris
НЕ приравнивается к #CC0000
, а скорее #C00000
очень похожий, но немного другой оттенок красного. Я использовал дополнение Firefox ColorZilla, чтобы проверить это.
Правила гласят:
- сделайте строку длиной, кратной 3, добавив 0:
chucknorris0
- разделите строку на 3 строки одинаковой длины:
chuc knor ris0
- обрезать каждую строку до 2 символов:
ch kn ri
- сохраните шестнадцатеричные значения и добавьте 0, где это необходимо:
C0 00 00
Я смог использовать эти правила для правильной интерпретации следующих строк:
LuckyCharms
Luck
LuckBeALady
LuckBeALadyTonight
GangnamStyle
ОБНОВЛЕНИЕ: оригинальные ответчики, которые сказали, что цвет был #CC0000
с тех пор отредактировал свои ответы, чтобы включить исправление.
Причина в том, что браузер не может понять это и пытается каким-то образом перевести это в то, что он может понять, и в этом случае в шестнадцатеричное значение!...
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";
Я также добавил шаги на изображении в качестве краткого справочника:
Большинство браузеров просто игнорируют любые не шестнадцатеричные значения в вашей цветовой строке, заменяя не шестнадцатеричные цифры нулями.
ChuCknorris
переводит на c00c0000000
, На этом этапе браузер разделит строку на три равные части, указывая значения Red, Green и Blue: 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>
Браузер пытается конвертировать chucknorris
в шестнадцатеричный код цвета, потому что это недопустимое значение.
- В
chucknorris
все кромеc
не является допустимым шестнадцатеричным значением. - Таким образом, он преобразуется в
c00c00000000
, - Которая становится # c00000, оттенок красного.
Похоже, что это проблема в первую очередь для Internet Explorer и Opera (12), так как Chrome (31) и Firefox (26) просто игнорируют это.
PS Цифры в скобках - это версии браузера, на которых я тестировал.
,
На более легкой ноте
Чак Норрис не соответствует веб-стандартам. Веб-стандарты соответствуют ему. #BADA55
HTML-спецификация WHATWG имеет точный алгоритм анализа устаревшего значения цвета: https://html.spec.whatwg.org/multipage/infrastructure.html
Код 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;
}
Ответ:
- Браузер попытается преобразовать chucknorris в шестнадцатеричное значение.
- поскольку
c
единственный допустимый шестнадцатеричный символ в chucknorris, значение превращается в:c00c00000000
(0 для всех значений, которые были недействительными). - Затем браузер делит результат на 3 группы:
Red = c00c
,Green = 0000
,Blue = 0000
, - Поскольку действительные шестнадцатеричные значения для фонов html содержат только 2 цифры для каждого типа цвета (r, g, b), последние 2 цифры усекаются из каждой группы, оставляя значение rgb равным
c00000
цвет кирпично-красный.
chucknorris - это статистика, в которой браузер считывает шестнадцатеричное значение.
потому что a,b,c,d,e,f символы в шестнадцатеричном
Браузерchucknorris
преобразовать вc00c00000000
шестнадцатеричное значение.
затемc00c00000000
шестнадцатеричное значение преобразуется в форматRGB (делится на 3)
c00c00000000
=>R:c00c,G:0000,B:0000
Браузеру нужны только 2 цифры для обозначения цвета.
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>
Правила синтаксического анализа цветов унаследованных атрибутов включают в себя дополнительные шаги, чем те, которые упомянуты в существующих ответах. Компонент усечения до двухзначной части описывается как:
- Отменить все символы, кроме последних 8
- Сбрасывать начальные нули один за другим, пока все компоненты имеют начальный ноль
- Отменить все символы, кроме первых 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> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>
Ответ простыми словами:
Короткий ответ заключается в том, что HTML отчаянно пытается угодить и примет практически все, что вы ему дадите. HTML построен на намеренном игнорировании искаженного ввода.
Вся концепция:
HTML принимает не шестнадцатеричный символ как 0, поэтому мы все знаем, что 0-9 определяют от нуля до девяти, а AF определяют от десяти до пятнадцати. Так что есть так много слов, которые могут быть как цвета «чакноррис», так и цвета глубокого кроваво-красного цвета, как этот. и аналогично «Стивенсегал» означает зеленый.
Отображение неожиданных цветов: если вы помещаете в bgcolor какое-либо слово, содержащее несколько шестнадцатеричных символов, этот символ покажет вам неожиданный цвет, который вы даже не представляете. Это работает так, как будто #F00F00 равно #FotFot. Но это будет работать только с bgcolor внутри тега таблицы и нигде больше.
Демо:
Просто наткнулся на это. Это очень интересная функция HTML, позвольте мне поделиться своими мыслями, и вы можете прокомментировать , прав я или нет - это поможет мне узнать больше.
При разборе цветов недопустимые цифры считаются равными 0 . Так,
chucknorris => c00c0000000
Он разделен на 3 части (r, g, b). Так,
chucknorris => c00c 0000 000
Учитываются только первые две цифры. Так,
chucknorris => c0 00 00
А также,
RGB(c0, 00, 00) is RED.
Думаю, теперь вы понимаете, почему chucknorr => желтый .