Чому 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.