Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
259 views
in Technique[技术] by (71.8m points)

html - Why are 3-digit hex color code values interpreted differently in Internet EXPLORER?

How exactly is Internet Explorer interpreting them, and under which guideline or set of standards?

For instance:

#FFF

is seem as the color white in Google Chrome, for instance, whereas in Internet Explorer (I tested it on 8 and 9) it appears as black.

I code I used to test this was as follows:

<body bgcolor="#ffffff"> vs. <body bgcolor="#fff">

(I am aware that bgcolor is deprecated, it was just convenient for what I was accomplishing at hand).

I am also aware that this is a bug, and that it can be easily fixed by appending a few digits (all-in-all 6) to the hexcode, but I am just interested in seeing the science behind why it occurs, if there is an explanation for it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since you are "interested in seeing the science behind why it occurs, if there is an explanation for it"...

TLDR:

'Color-values' are not 'universal'.

The abbreviated/shorthand three-digit hexadecimal #RGB form is described in the CSS specification, not in HTML. As a result, the three-digit form in an attribute other than "style" or inside a <style> tag is not interpreted as a valid color in some browsers.
https://en.wikipedia.org/wiki/Web_colors



In depth:

I'm starting with the CSS 1 spec, Color units (6.3) (as it introduces some terms/concepts I then don't have to repeat), which specifies:

A color is a either a keyword or a numerical RGB specification.

The suggested list of keyword color names is: aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white, and yellow. These 16 colors are taken from the Windows VGA palette, and their RGB values are not defined in this specification.

BODY {color: black; background: white }
H1 { color: maroon }
H2 { color: olive }

The RGB color model is being used in numerical color specifications. These examples all specify the same color:

EM { color: #f00 }              /* #rgb */
EM { color: #ff0000 }           /* #rrggbb */
EM { color: rgb(255,0,0) }      /* integer range 0 - 255 */
EM { color: rgb(100%, 0%, 0%) } /* float range 0.0% - 100.0% */

The format of an RGB value in hexadecimal notation is a '#' immediately followed by either three or six hexadecimal characters. The three-digit RGB notation (#rgb) is converted into six-digit form (#rrggbb) by replicating digits, not by adding zeros. For example, #fb0 expands to #ffbb00. This makes sure that white (#ffffff) can be specified with the short notation (#fff) and removes any dependencies on the color depth of the display.

The format of an RGB value in the functional notation is 'rgb(' followed by a comma-separated list of three numerical values (either three integer values in the range of 0-255, or three percentage values in the range of 0.0% to 100.0%) followed by ')'. Whitespace characters are allowed around the numerical values.

Values outside the numerical ranges should be clipped. The three rules below are therefore equivalent:

EM { color: rgb(255,0,0) }       /* integer range 0 - 255 */
EM { color: rgb(300,0,0) }       /* clipped to 255 */
EM { color: rgb(110%, 0%, 0%) }  /* clipped to 100% */

RGB colors are specified in the sRGB color space. UAs may vary in the fidelity with which they represent these colors, but use of sRGB provides an unambiguous and objectively measurable definition of what the color should be, which can be related to international standards.

In the context of CSS, with regard to browser-support, the only 2 'interesting' things I could find were:

  • All browsers that support style sheets (version 3 and above, except IE3 Mac) support this three-character shorthand form of hexadecimal colors (Sources: 1, 2, "Optimize CSS Colors" by King A.B.)
    Note the historical timeframe of that text.. IE3... on Mac... Browsers like FireFox 1 or Chrome weren't even around back then..
  • The two rgb() methods suffer from Internet Explorer 3's non-support for them
    Source: 1 (very good read)



According to the HTML4 spec, the attribute bgcolor was only for <body>, <table>, <tr>, <th> and <td>. (So as far as the legacy spec is concerned, one can not use it on a <div> for example.)

All of them are of the CDATA-type: %Color;
which was defined as:

<!ENTITY % Color "CDATA" -- a color using sRGB: #RRGGBB as Hex values -->

<!-- There are also 16 widely known color names with their sRGB values:

    Black  = #000000    Green  = #008000
    Silver = #C0C0C0    Lime   = #00FF00
    Gray   = #808080    Olive  = #808000
    White  = #FFFFFF    Yellow = #FFFF00
    Maroon = #800000    Navy   = #000080
    Red    = #FF0000    Blue   = #0000FF
    Purple = #800080    Teal   = #008080
    Fuchsia= #FF00FF    Aqua   = #00FFFF
 -->

The magic phrase here is: "a color using sRGB: #RRGGBB as Hex values".

If I read this wearing a specification-implementor's hat, I must agree that I don't see short-hand 3-digit #RGB notation specified and I would not have implemented it (neither would I have implemented RGB(DDD,DDD,DDD)).

As for HTML5, the bgcolor attribute is obsoleted for all previous (HTML4) specified elements (see above).
That means that, in regard to specification, the format of valid 'color-codes' is not going to change any time soon..



Conclusion:

Accepting only a named color (from a specified/supported list) or a 'hex triplet' (format #RRGGBB) sRGB color-value on the HTML attribute bgcolor is not a bug; it is per spec!
Cross-Browser solution: .. see spec ?

If one mistakingly specifies a short-hand color-value for bgcolor on a parsing/rendering engine that doesn't support that, then either nothing happens or a unintended color might show; effectively you have entered 'Chuck Norris'-land..
Most notably for MS IE and MS Outlook, the colors will seem almost black. For example: #ff0 (shorthand) will become #0f0f00 (instead of #ffff00). Another example: #07c will become #00070c, etc.
However some other implementations turn #ff0 into #000ff0 and #07c into #00007c!! If one mistakingly specifies an RGB(RRR,GGG,BBB) value for bgcolor, all kinds of colors can appear, for example RGB(255,255,255) can become a very dark shade of green source, etc.

So here we have a fun example where Microsoft's Internet Explorer (all known versions, including IE11) did follow the spec and a lot of people still complain..
I found countless bug-rapports regarding "the 3-digit color-value shorthand 'bug' for the bgcolor-attribute" (spanning over 15 years) addressed at for example MS IE, alternative browsers using MS IE HTML parse/rendering engine and the majority of local-app/webbased Email-clients like Gmail, (all versions of) Outlook(-Express), Lotus Notes, Android, etc. etc. etc. (for example 1, 2, 3, 4, 5, etc.)

Why the complaints/bug-rapports?
Because some other browsers (like FireFox, Chrome) did/do support color-values in other formats then #RRGGBB on HTML's attribute bgcolor.
Why do others support it?
I have just 2 guesses: (a) It's a leftover from "BrowserWar 1" where one of the battles was around "My browser can make 'sense' of bigger cr@p-code then the competitor's", but somewhat more likely would be (b) reusing the code from the CSS color-value parser... eventually I would have done that as well



Extra:

Why would anyone anno 2015 still care about bgcolor?
Why does that still generate such an amount of bug-rapports and questions?
The answer is HTML Email...
In theory (to the unsuspecting web-developer) it's 'just HTML and CSS'..
In practice it's amazingly hard (1) to get right. Think: all cross-browser issues that ever existed to the power of 3 !
It has to work on far more E-mail clients on numerous platforms (loads of 'legacy' applications that are actually still in use), it must also work in web-based clients like Gmail, AOL, Yahoo, Hotmail, etc. etc.
Not only must they code for the lowest common denominator imaginable (much techniques were already considered ancient a fat decade ago), they must even try to 'fit in' with the layout/style of some of the web-based clients.

Their typical structure is one big background table, then one div, then one main table, and nested tables if needed...
To put things into further perspective, according to litmus (anno 2014):
"It turns out that the most reliable way of coding background colors is to use the HTML bgcolor attribute with a 6-digit hex code on the table and td level"



Clearly this 'mess' is not going to dis-appear soon and a common thing for a web-developer is to code/design HTML e-mail... Therefore I think that a good complete understanding (and answer to this matter) is still very relevant anno 2015 and the near future.

Hope this helps!

PS: MS IE's filter: progid:DXImageTransform.Microsoft.gradient also doesn't accept 3-digit hex shorthand color values, but now that one is reminded of the notion that 'Color-Values are not Universal', this is less of a surprise (and not a bug unless it was specified that it would accept such values).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...