Чому HTML думає, що "chucknorris" - це колір?


7486

Яким чином певні випадкові рядки створюють кольори, коли вводяться як кольори фону в HTML? Наприклад:

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

... створює документ з червоним фоном у всіх браузерах та платформах.

Цікаво, що, хоча і chucknorriстворює червоний фон, він chucknorrстворює жовтий фон.

Що тут відбувається?


154
Як бічна примітка: не використовуйте bgcolor. Використовуйте CSS background.
Джон Дворак

47
Чому ви коли-небудь хочете додати колір фону під назвою chucknorris? Яким був очікуваний колір?
майстерFly

106
@masterFly: Я не знаю, чому мій коментар під прийнятою відповіддю був видалений за те, що він "не конструктивний", тому що він відповідає на ваше запитання досить добре: люди постійно експериментують з цими речами. Мені було лише 10 років, коли я виявив це, і все, що я робив у той час, було возитися і бачити, що сталося. Ви не завжди повинні мати практичну причину, щоб щось робити, особливо щось таке легковажне, як це.
BoltClock

49
і <body bgcolor="stevensegal">тест </body> зелений
Кріс

4
@BenDaggers Будь ласка, прочитайте історію редагувань, перш ніж вносити інші зміни. CSS тег не має ніякого відношення і вже двічі був знищений.
Гонки легкості по орбіті

Відповіді:


6878

Це перехід від днів Netscape:

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

Це з публікації в блозі Невелика розмова про розбір кольорів Internet 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>

Це також відповідає іншій частині питання; чому bgcolor="chucknorr"утворюється жовтий колір? Що ж, якщо ми застосуємо правила, рядок:

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

Що дає світло-жовтий золотий колір. Оскільки рядок починається з 9 символів, ми зберігаємо другий C на цей раз навколо, отже, він закінчується в кінцевому значенні кольору.

Я спочатку стикався з цим, коли хтось вказував, що ти можеш зробити, color="crap"і, ну, виходить коричневий.


174
Зауважте, що, незважаючи на те, що написано в цій публікації блогу, коли ви переходите до обробки 3-рядових рядків, ви дублюєте кожен символ, а не попередньо додаєте 0. тобто 0F6стає #00FF66, не #000F06.
Аарон Дюфур

634
@usr: HTML побудований навколо навмисного ігнорування неправильного введення;)
Лілі Баллард

59
Ви також можете використовувати мій випадковий рядок, щоб перетворити колірний конвертер css, щоб отримати колір для певної рядки. Він заснований на 5 кроках, щоб обчислити колір рядка від Джеремі Гудела .
TimPietrusky

15
Прихована можливість для семантики? Ви можете зробити кілька сторінок помилок з цим: <body bgcolor=error><h1 style=text-align:center>Error: Not Found<h1></span>Ви можете додати div з іншим фоном чи чимось подібним, так що це не так естетично шокує.
Тераот

32
@Theraot bgcolor="success"теж хороший зелений. Цікаво, що ці кольори можна змінити за допомогою селекторів атрибутів / значень CSS (наприклад, td[bgcolor="chucknorris"] {...}).
дайског

970

Вибачте, не погоджуючись, але відповідно до правил розбору застарілого значення кольору, опублікованих @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тих пір редагували їхні відповіді, включали виправлення.


86
Я зрозумів це, я неправильно інтерпретував деякі інструкції розбору: "adamlevine" = "ada00e000e" = "ada00e000e00" = "ada0 0e00 0e00" = "ad 0e 0e" - Ідеально !!
Джеремі Гудделл

17
У випадку, якщо вас цікавить, я розмістив 5-ступінчастий алгоритм як ОНОВЛЕННЯ на аналогічне запитання, яке я опублікував сьогодні: stackoverflow.com/questions/12939234/…
Джеремі Гудделл

18
@TimPietrusky створив цей чудовий неймовірний демонстраційний інструмент для випадкових імен кольорів. Просто перейдіть сюди: randomstringtocsscolor.com і натисніть на поле і введіть "chucknorris".
Jeremy Goodell

4
adamlevineпрацює відповідно до jsfiddle.net/LdyZ8/2959, але листи заблоковані, вкладеніada00e000e до, ada00e000e00але потім зменшені до типового значення HEX 6, [ad]a0[0e]00[0e]00таким чином роблячи ad0e0e, яке відображається у jsfiddle вище.
Мартін

4
Було б краще , якби ця відповідь тільки містив поточний стан - історія цієї відповіді і інших відповідей належить в редагуванні резюме і / або коментарях.
Пітер Мортенсен

397

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

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>


7
Хоча мені все ще цікаво, чому ОП сказав "в CSS", а не "в HTML" - можливо, вони використовують надто старий браузер, або просто помиляються?
Майк Крістенсен

7
Тож він скоріше за все використовує bgcolorатрибут застарілого .
animuson

12
Недійсні символи не пропускаються, вони трактуються як 0.
добре

5
(Хоча ця відповідь може бути мертвою) пропозиція: Використовуйте замість цього колір фону, щоб продемонструвати кольори. Колір тексту над такою невеликою відносною площею, важко помітити відмінності чи схожість
Зоя,

304

Браузер намагається перетворити chucknorrisв шістнадцятковий кольоровий код, тому що це невірне значення.

  1. У chucknorris, все, крімc не є дійсним шістнадцятковим значенням.
  2. Таким чином, він перетворюється на c00c00000000 .
  3. Що стає # c00000 , червоний відтінок.

Здається, це проблема, перш за все, для Internet Explorer і Opera (12), оскільки Chrome (31) і Firefox (26) просто ігнорують це.

PS Номери в дужках - це версії браузера, на яких я тестувався.

.

На більш легкій ноті

Чак Норріс не відповідає веб-стандартам. Веб-стандарти відповідають йому. # BADA55


296

Причина в тому, що браузер не може його зрозуміти і спробувати якось перевести його на те, що він може зрозуміти, і в цьому випадку в шістнадцяткове значення! ...

chucknorrisпочинається з того, cщо розпізнається символом у шістнадцятковий, також він перетворює всі нерозпізнані символи в0 !

Так chucknorrisу шістнадцятковому форматі стає:, c00c00000000всі інші символи стають 0і cзалишаються там, де вони є ...

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

Але ми знаємо, що дійсний шістнадцятковий для RGB - це лише два символи, значить R: c0, G: 00, B:00

Отже, реальний результат такий:

bgcolor="#c00000";

Я також додав кроки на зображенні як швидку довідку для вас:

Чому HTML думає, що "chucknorris" - це колір?


23
Це таке миле пояснення: D: D: D
Домінік

2
Настільки мудре і дуже просте і пряме пояснення, яке я коли-небудь відчував
Саурін Вала

1
дуже креативна відповідь :)
ahmednawazbutt

222

Специфікація WHATWG HTML має точний алгоритм розбору застарілого значення кольору: 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;
}

Дякую, ви показали мені, де знаходиться старий вихідний код Netscape ... чому його так важко знайти?
kb1000

202

Відповідь:

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

22

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>


15

В правила розбору кольорів на застарілих атрибутів включає в себе додаткові кроки , ніж ті , які згадані в існуючих відповідях. Компонент усікання до двоцифрової частини описується як:

  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

Нижче наведено часткову реалізацію алгоритму. Він не обробляє помилки або випадки, коли користувач вводить дійсний колір.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.