Why does HTML think “chucknorris” is a color?

6 731

1 668

How come certain random strings produce colors when entered as background colors in HTML? For example:

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

...produces a document with a red background across all browsers and platforms.

Interestingly, while chucknorri produces a red background as well, chucknorr produces a yellow background.

What's going on here?

user456584

Posted 2011-11-29T22:54:22.833

Reputation: 34 826

84As a side note: don't use bgcolor. Use CSS background. – John Dvorak – 2016-09-04T12:40:40.043

14Why do you ever want to add a background color called chucknorris? What was the expected color? – masterFly – 2016-11-24T05:01:13.653

46@masterFly: I don't know why my comment under the accepted answer was deleted for being "not constructive", because it answers your question quite well: people experiment with these things all the time. I was only 10 when I discovered this and all I was doing at the time was messing around and seeing what happened. You don't always have to have a practical reason for doing something, especially something as frivolous as this. – BoltClock – 2016-12-01T03:36:11.123

15and &lt;body bgcolor="stevensegal"&gt; test </body> is green – Chris – 2017-10-01T08:45:32.087

Answers

6 213

It's a holdover from the Netscape days:

Missing digits are treated as 0[...]. An incorrect digit is simply interpreted as 0. For example the values #F0F0F0, F0F0F0, F0F0F, #FxFxFx and FxFxFx are all the same.

It is from the blog post A little rant about Microsoft Internet Explorer's color parsing which covers it in great detail, including varying lengths of color values, etc.

If we apply the rules in turn from the blog post, we get the following:

  1. Replace all nonvalid hexadecimal characters with 0's

    chucknorris becomes c00c0000000
    
  2. Pad out to the next total number of characters divisible by 3 (11 -> 12)

    c00c 0000 0000
    
  3. Split into three equal groups, with each component representing the corresponding colour component of an RGB colour:

    RGB (c00c, 0000, 0000)
    
  4. Truncate each of the arguments from the right down to two characters

Which gives the following result:

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

Here's an example demonstrating the bgcolor attribute in action, to produce this "amazing" colour swatch:

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

This also answers the other part of the question; why does bgcolor="chucknorr" produce a yellow colour? Well, if we apply the rules, the string is:

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

Which gives a light yellow gold colour. As the string starts off as 9 characters, we keep the second C this time around hence it ends up in the final colour value.

I originally encountered this when someone pointed out you could do color="crap" and, well, it comes out brown.

dash

Posted 2011-11-29T22:54:22.833

Reputation: 71 463

141Note that, despite what that blog post says, when you get to handling 3-char strings, you duplicate each character, rather than prepending 0. i.e. 0F6 becomes #00FF66, not #000F06. – Aaron Dufour – 2013-02-05T20:32:22.607

569@usr: HTML is built around intentionally ignoring malformed input ;) – Lily Ballard – 2013-02-05T23:43:02.660

50

You can also use my random string to css color converter to get the color for a specific string. It's based on the 5 steps to calculate the string color by Jeremy Goodell.

– TimPietrusky – 2013-03-11T16:45:17.353

11A hidden opportunity for semantics? You could make some error pages with this: &lt;body bgcolor=error&gt;&lt;h1 style=text-align:center&gt;Error: Not Found&lt;h1&gt;&lt;/span&gt; You could add a div with anothe background or something like that, so it is not that aesthetically shocking. – Theraot – 2013-12-16T22:47:35.440

2Why do it truncate from the right instead of keeping the low significant digits like normal arithmatics in computers do? – phuclv – 2014-08-07T05:40:06.303

8@LưuVĩnhPhúc Because this way preserves the colour ratio. Ultimately, you'll convert your colour to a percentage of the maximum value: if you're trying to convert f05 in one of your channels, 0xf0 / 0xff is a lot closer than 0x05/0xff to 0xf05 / 0xfff – 3Doubloons – 2014-09-15T04:15:46.537

21

@Theraot bgcolor="success" is a nice green, too. Interestingly, one can override these colours using CSS attribute/value selectors (e.g., td[bgcolor="chucknorris"] {...}).

– megaflop – 2016-03-01T12:39:17.590

2@AaronDufour that is actually logical; the most accurate representation of 6 on a scale of F when converted to a scale of FF is indeed 66. If you don't do that, the higher the value is, the more it'll deviate from the intended colour: FFF, which is meant to be white, should become FFFFFF, not F0F0F0. I encountered this problem when generating 16-colour gradient palettes. – Nyerguds – 2016-12-22T13:42:18.963

@TimPietrusky I get a different results in Chrome and your converter when I plug in the name "veronica" – tvanc – 2017-01-20T17:11:00.057

I tip my hat to you, @dash. Amazing explanation. I was leaning towards #9 in this list: http://codesqueeze.com/the-ultimate-top-25-chuck-norris-the-programmer-jokes/

– SDsolar – 2017-06-03T18:54:44.210

2Reminds me of discovering that div color="crap" is, indeed, a brownish colour in old-skool HTML4 (if you can find a browser that will still render it :-) – Dave Everitt – 2018-02-03T12:54:33.140

@Theraot: Too bad bgcolor is a presentational attribute and therefore carries zero semantic value, making it functionally equivalent to class="error" while being invalid, and 2 bytes longer. – BoltClock – 2018-02-07T05:30:56.820

1@Dave Everitt: I left a similar anecdote here many years ago (which I allude to in a comment on the question) and it got flagged and deleted - twice. C'est la vie. – BoltClock – 2018-02-07T05:33:52.127

@TimPietrusky chucknorr like in OP's question doesn't output the expected yellowish rgb(192, 192, 0) – Thomas Mulder – 2018-05-14T13:37:52.047

1

You're missing the rules to correctly compute &lt;body bgcolor="dog"&gt;: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-a-legacy-colour-value

– Mikko Rantalainen – 2018-09-05T07:27:01.303

@MikkoRantalainen in this case, if it has that color, you should take it to the vet. – Ismael Miguel – 2018-09-22T16:30:17.847

853

I'm sorry to disagree, but according to the rules for parsing a legacy color value posted by @Yuhong Bao, chucknorris DOES NOT equate to #CC0000, but rather to #C00000, a very similar but slightly different hue of red. I used the Firefox ColorZilla add-on to verify this.

The rules state:

  • make the string a length that is a multiple of 3 by adding 0s: chucknorris0
  • separate the string into 3 equal length strings: chuc knor ris0
  • truncate each string to 2 characters: ch kn ri
  • keep the hex values, and add 0's where necessary: C0 00 00

I was able to use these rules to correctly interpret the following strings:

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle

UPDATE: The original answerers who said the color was #CC0000 have since edited their answers to include the correction.

Jeremy Goodell

Posted 2011-11-29T22:54:22.833

Reputation: 12 154

75I figured it out, I had misinterpreted some of the parsing instructions: "adamlevine" = "ada00e000e" = "ada00e000e00" = "ada0 0e00 0e00" = "ad 0e 0e" -- Perfect!! – Jeremy Goodell – 2012-10-17T18:11:21.853

14

In case you're interested, I posted the 5-step algorithm as an UPDATE on a similar question I posted today: http://stackoverflow.com/questions/12939234/why-do-weird-things-in-font-color-attribute-produce-real-colors

– Jeremy Goodell – 2012-10-17T18:50:28.060

14

@TimPietrusky created this freaking incredible demo tool for random color names. Just go here: http://randomstringtocsscolor.com/ and click in the box and type "chucknorris".

– Jeremy Goodell – 2014-02-06T19:01:38.567

3adamlevine does work as per http://jsfiddle.net/LdyZ8/2959/ but the letters are blocked into ada00e000e which is padded to ada00e000e00 but then reduced down to the typical HEX 6 digit value of [ad]a0[0e]00[0e]00 thus making ad0e0e which appears in the jsfiddle above. – Martin – 2016-01-26T22:26:26.013

2It would be better if this answer only contained the current state - the history of this answer and other answers belongs in the edit summaries and/or comments. – Peter Mortensen – 2016-01-31T12:13:22.407

345

Most browsers will simply ignore any NON-hex values in your color string, substituting non-hex digits with zeros.

ChuCknorris translates to c00c0000000. At this point, the browser will divide the string into three equal sections, indicating Red, Green and Blue values: c00c 0000 0000. Extra bits in each section will be ignored, which makes the final result #c00000 which is a reddish color.

Note, this does not apply to CSS color parsing, which follow the CSS standard.

<p><font color='chucknorris'>Redish</font></p>
<p><font color='#c00000'>Same as above</font></p>
<p><span style="color: chucknorris">Black</span></p>

Mike Christensen

Posted 2011-11-29T22:54:22.833

Reputation: 55 858

6Though I'm still curious as to why OP said "in CSS" and not "in HTML" - Maybe they're using a super old browser, or just mistaken? – Mike Christensen – 2011-11-29T23:19:12.420

6So then he is more than likely using the deprecated bgcolor attribute. – animuson – 2011-11-29T23:20:15.680

10Perhaps he will be so kind as to post this magical HTML that produces a Chuck Norris red across "all browsers and platforms." – Mike Christensen – 2011-11-29T23:22:09.410

10Invalid characters are not skipped, they are treated as 0. – phyzome – 2012-09-28T03:30:30.997

3(WHile this answer may be dead) suggestion: Use background color instead to demonstrate teh colors. Text color is over such a small relative area it is hard to see differences or similarities – Zoe – 2017-06-07T11:37:08.197

237

The browser is trying to convert chucknorris into hex colour code, because it's not a valid value.

  1. In chucknorris, everything except c is not a valid hex value.
  2. So it gets converted to c00c00000000.
  3. Which becomes #c00000, a shade of red.

This seems to be an issue primarily with Internet Explorer and Opera (12) as both Chrome (31) and Firefox (26) just ignore this.

P.S. The numbers in brackets are the browser versions I tested on.

.

On a lighter note

Chuck Norris doesn't conform to web standards. Web standards conform to him. #BADA55

aWebDeveloper

Posted 2011-11-29T22:54:22.833

Reputation: 18 736

For those interested, #BADA55 yields RGB(186, 218, 55), a nice shade of puke green... I guess MS literally interprets a "bad ass" as a bad digestive system... lol – vapcguy – 2018-11-28T22:57:30.780

195

The WHATWG HTML spec has the exact algorithm for parsing a legacy color value: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

The code Netscape Classic used for parsing color strings is open source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

For example, notice that each character is parsed as a hex digit and then is shifted into a 32-bit integer without checking for overflow. Only eight hex digits fit into a 32-bit integer, which is why only the last 8 characters are considered. After parsing the hex digits into 32-bit integers, they are then truncated into 8-bit integers by dividing them by 16 until they fit into 8-bit, which is why leading zeros are ignored.

Update: this code does not exactly match what is defined in the spec, but the only difference there is a few lines of code. I think it is these lines that was added (in Netscape 4):

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

Yuhong Bao

Posted 2011-11-29T22:54:22.833

Reputation: 3 163

173

Answer:

  • The browser will try to convert chucknorris into a hexadecimal value.
  • Since c is the only valid hex character in chucknorris, the value turns into: c00c00000000(0 for all values that were invalid).
  • The browser then divides the result into 3 groupds: Red = c00c, Green = 0000, Blue = 0000.
  • Since valid hex values for html backgrounds only contain 2 digits for each color type (r, g, b), the last 2 digits are truncated from each group, leaving an rgb value of c00000 which is a brick-reddish toned color.

Webeng

Posted 2011-11-29T22:54:22.833

Reputation: 5 313

158

The reason is the browser can not understand it and try to somehow translate it to what it can understand and in this case into a hexadecimal value!...

chucknorris starts with c which is recognised character in hexadecimal, also it's converting all unrecognised characters into 0!

So chucknorris in hexadecimal format becomes: c00c00000000, all other characters become 0 and c remains where they are...

Now they get divided by 3 for RGB(red, green, blue)... R: c00c, G: 0000, B:0000...

But we know valid hexadecimal for RGB is just 2 characters, means R: c0, G: 00, B:00

So the real result is:

bgcolor="#c00000";

I also added the steps in the image as a quick reference:

Why does HTML think “chucknorris” is a color?

Alireza

Posted 2011-11-29T22:54:22.833

Reputation: 43 514

7

chucknorris is stats with c the browser read into a hexadecimal value.

because a,b,c,d,e,f are characters in hexadecimal

The browser chucknorris convert to c00c00000000 hexadecimal value.

Then c00c00000000 hexadecimal value convert to RGB format(divided by 3)

c00c00000000 => R:c00c,G:0000,B:0000

The browser needs only 2 digits to indicate the colour.

R:c00c,G:0000,B:0000 => R:c0,G:00,B:00 => c00000

finally, show bgcolor = c00000 in web browser.

Here's an example demonstrating

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

sameera lakshitha

Posted 2011-11-29T22:54:22.833

Reputation: 1 114

0

The rules for parsing colors on legacy attributes involves additional steps than those mentioned in existing answers. The truncate component to 2 digits part is described as:

  1. Discard all characters except the last 8
  2. Discard leading zeros one by one as long as all components have a leading zero
  3. Discard all characters except the first 2

Some examples:

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

Below is a partial implementation of the algorithm. It does not handle errors or cases where the user enters a valid color.

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>

Salman A

Posted 2011-11-29T22:54:22.833

Reputation: 172 519