Have you ever tried to set something weird as a background color like
bgcolor="foo bar baz"? Chances are you haven’t, because you’re smart, aware of hex / rgb rules and you know that some attributes are deprecated in html5 anyway. But the fact remains that you can display literally anything as a color in all modern browsers.
Let’s have a look at the following examples:
foo bar baz,
I'm the president,
James Star. Here are the results:
|input:||foo bar baz||I'm the president||1r2a3n4d5o6m7w8o9r0d||James Star|
|expected:||rgb(240, 186, 186)||rgb(0, 224, 13)||rgb(16, 213, 128)||rgb(10, 0, 160)|
So the question is, how does a webbrowser interpret invalid strings and converts them to a valid color?
All major webbrowsers use an algorithm for this. The most important points are:
- Strip whitespaces from string.
- Check if string is multiple of three. If not, add
0‘s to the string until it is.
- Change each non-hexadecimal value (0-9,a-f) to
- Divide string into three equal length substrings.
- Truncate each resulting substring to two characters.
- Display resulting color (with RGB values).
- Strip whitespaces:
I'm the presidentbecomes
- Multiple of three? Yes,
I'mthepresident= 15 characters.
- Change non-hex to
- Three equal length parts:
- Truncate each string to two characters:
- Display as RGB:
0d=> 0*16+13=13. Result:
Try it yourself!
Some suggestions you might want to try:
- Your name
- Your favorite meal
- Name of your boss
- Your favorite website
- Names of celebrities
- This website
How to convert Hex to RGB
Before we get to the more special stuff, lets be sure that you know how to convert Hex to RGB properly. It’s really simple. While the hexadecimal values
0-9 means just that,
a-f calculates as
10-15. You normally have six values total, led by a
#123456. Just pair them to groups:
56. To convert to RGB, the first number of each group gets multiplied by 16. The second number just gets added to the result of the first number. It acts as an “offset” which means it has not such a big impact on the final result as the first number. Here is an example:
#123456 => 12 34 56 => convert to RGB: 1*16+2 3*16+4 5*16+6 => rgb(18,52,86)
Now we can look at some special cases where the results differ from what is expected. The short answer at the beginning works for almost anything. However, there are some exceptions.
- Hardcoded words: 140 colornames like
whiteetc are hardcoded and will just return the associated color. Additionally, the word
transparent(or no input at all) will not generate a color value.
- Long inputs: Your string may not be longer than 128 characters. This is the limit. Additional characters get truncated.
- If the resulting three substrings are longer than eight characters, the leading characters are removed until there are only eight left. So
34567890which in turn becomes
- Also, if all your substrings start with one or more leading
0‘s, they will get removed. While
0xy23456(reduced to eight characters) and in the next step becomes
23456(because all substrings had technically three leading
0‘s). The final result would be
- Short inputs (no leading
- One character: One hex value (0-9,a-f) results in
rgb(0-240,0,0)(note: This only applies for one, two and three character inputs), everything else is set to
- Two characters: The second value determines the green portion of RGB (not the offset red portion). The input
- Three characters: The third value determines the blue portion of RGB (not the first green portion). The input
- Four characters: The first two values determine the red portion of RGB (note: From now on the values range from
0-15+offset). The last two values determine the green portion of RGB. The input
- Five characters: The fifth value determines the main blue portion of RGB. So
- Short inputs (with leading
- One character: Same as without leading
- Two characters: Same as without leading
- Three characters: Major changes. The algorithm duplicates each value after the leading
#5a1is treated as
- Four characters: Same as without leading
- Five characters: Same as without leading
- If there are more than six characters and a leading
#, then simply remove the leading
Can’t remember all this, too much geek info!
No problem. Here is the ultra short “works almost always and makes me happy” version:
“Count string. Divide by 3. Truncate each substring to two characters. Convert to RGB.”
This works 95% of the time for most commonly used invalid “colors”. If something unexpected happens, check for removable leading zeros. Then you’ll cover 99%. If result is still weird, check the length of substrings or just come back here and read about the other special cases.
Tried it, can’t get it to work!
It’s true that
bgcolor is deprecated and discontinued in html5, but it’s also still supported for a long time to come by all major browsers for compatibility reasons. Then “what am I doing wrong?” Well, invalid “colors” like these do not work via CSS. You’ll likely run into an “invalid property” warning. Since there is no css-property or css-attribute for
bgcolor, it appears you can only apply these kinds of “colors” with
bgcolor directly to the appropriate elements. These are
body. If you applied it to let’s say a
div– or a
p-tag, you are right, it won’t work.
Hope you found this post useful and that it cleared up a few things for you. So, have a nice day!