|
|||||||
|
|||||||
|
Internet Explorer 4 represented a huge advance over Internet Explorer 3 in every department, and CSS was no exception. It presented the first usable implementation of CSS, and now, 3 years on, the situation is little different - Opera has introduced reasonable support to a tiny number of die-hards, Netscape's support is execrable, and IE 5, although something of an improvement, was not as big a jump as IE 4 was. However, while many bugs were fixed from version 3, not all of them were, and new features inevitably brought new bugs, which I detail below.
Although IE 4 is no longer distributed by Microsoft, it retains a lead in market share over IE 5, and so therefore it is of enormous importance to those using CSS.
If you want to know the extent of the problem, about 30% of all web users are using IE 4.
I urge you most strongly to use RichInStyle.com's browser-detection methods, so that the fixes made for IE 4 don't damage other browsers.
These have sorted into categories. This should make it easy for to you find whether the property that you want to use works.
While it should be easily apparent what area you are using, and therefore which section you should read, everyone uses Section A and Section B, so therefore everyone should read these sections.
Section A - Bugs relating to the attachment of styles to pages (26 bugs)
Section B - Bugs relating to the application of styles to elements (26 bugs)
Section C - Bugs relating to key concepts (26 bugs)
Section D - Bugs with units (3 bugs)
Section E - Font bugs (14 bugs)
Section G - Color and background bugs (1 bug)
Section H - Margin and padding bugs (11 bugs)
Section I - Border bugs (8 bugs)
Section J - Width and height bugs (6 bugs)
Section K - Float and clear bugs (14 bugs)
Section L - Display, cursor and printing bugs (9 bugs)
Section M - Positioning bugs (5 bugs)
Section N - Form bugs (12 bugs)
Section P - Table bugs (10 bugs)
Section Q - List item bugs (10 bugs)
Section R - Error correction bugs (49 bugs)
Total bugs = 26 + 3 + 14 + 17 + 1 + 11 + 8 + 6 + 14 + 9 + 5 + 12 + 8 + 10 + 10 + 49 = 203.
Internet Explorer 4 won't allow you to link to style sheets via http-equiv LINK. This is a non-serious bug because it is madness to link to style sheets in this way anyway.
Although preferred style sheets (i.e., those specified using the title attribute) are mutually exclusive within titles, and therefore all except the last one should be ignored - IE 4 doesn't apply this, applying all of them regardless thus treating them as persistent. Again, this is non-serious because it is pointless to have more than one preferred style sheet on a page anyway.
IE 4 does not support alternate style sheets.
@media
According to the CSS 1 specification, all unknown @rules should be ignored. This is something IE 4 fails to do.
It correctly parses one line @rules (@import
and @charset
), but only
parses block @rules correctly if they do not contain other blocks.
As a result, @media
is parsed in the following manner: ignore the first ruleset of
the declaration block; apply all the rest of them.
@media handheld {
P {
color: white;
background: black;
}
BODY {color: red;
background: blue;
}
}
This example would cause the first ruleset (the P declaration) to be ignored, but the second one to be applied to ALL media.
Thus @media
(and any future block @rule that contains other blocks MUST be kept
away from IE 4. If you can't manage that, only include one ruleset inside each {} @rule, and follow
each with a dummy declaration (as in .dummy {color: red}
).
Unfortunately, IE only knows of } as used to close blocks. It parses { perfectly, except where it follows a (to it) 'wrong' '}'.
As a result, something like this would be parsed in a non-problematic way: P {color:
{{{{{{; font-size: green}
.
This, on the other hand, would be parsed wrongly: P {color: @value {eval (6 * @location
{url(cheeseburger)} ) }}
. What would occur here is that it would get to the first } (after
the cheesburger
) and would think 'Ah, this is the end of the block, so I've got a new
ruleset coming up'.
As a result, to give an example, it would parse:
P {
color: @value {eval (6 * @location {url(cheeseburger)} ) };
font-size: green
}
DIV {color: yellow}
As:
P {
color: @value {eval (6 * @location {url(cheeseburger)}}}
/* Next is what it treats as a ruleset! */
) }; font-size: green } DIV {
color: yellow
}
@import
IE 4 only supports @import
in the url
format, as in @import
url("import.css");
or @import url(import.css);
, but does not support it in the
form @import "import.css";
. Although this is a bug, it is useful, providing you are
aware of it, since it allows IE 4 to be excluded. (Note that IE does not support the CSS 2
@import
syntax that includes media - but then you wouldn't expect it to - it pre-dates CSS
2).
)
and ;
Although the definition of the @import
rule permits white space between the url and
the semi-colon, IE does not support this, and as a result, instead of @import url(css.css)
;
or @import url(css.css)
you must have the
;;
next to the closing bracket.
style
attributeThe style
attribute is given infinite specificity, rather than specificity of 100.
Although this is a bug, it should not be fixed.
Internet Explorer 4 does not allow users to disable style sheets, as is required (for accessibility reasons) by the CSS specification.
CSS 1 defined a DELIM
token, stating that all characters that couldn't form part of
selector tokens were delimiters. Thus, if IE 4 complied with CSS 1, it would ignore BODY *
P
(matching <P>
as at least the grandchild of <BODY>
in CSS 2 UAs). However, it doesn't and prefers to ignore all unknown delimiting characters and
everything before them, treating this example (BODY * P), for example, as P
.
The characters that are affected in CSS 2 are +
, >
and
*
; as CSS expands, the problems will get worse.
H1 + P {margin-top: 0} /* + and everything that comes before it is ignored, so
is considered to be P */
*:active {color: red} /* The * is ignored, so there is no problem */
BODY > P {margin-left: 10pt} /* Treated as BODY P */
:hover
:visited
vs. :hover
When (and only when) determining the styles to be applied to hovered over visited links, IE
treats both these selectors as if they read :visited:hover
.
For example:
A:hover {
color: white;
background: black;
}
A:visited {
color: black;
}
Would be parsed as:
A:hover:visited {
color: white;
background: black;
}
A:hover:visited {
color: black;
}
Which is the same as:
A:hover:visited {
color: black;
background: black;
}
Note that IE does apply the specificity sort here, so A:hover
would always apply
over :visited
.
:link
vs. :hover
This is sorted differently from :visited
vs. :hover
- whereas
:visited
vs. :hover
were sorted for the purposes of hovered over visited text
as if they were both :visited:hover
, these are sorted as if they were different, with
:hover
parsed as :link:hover
and :link simply as it is.
As a result:
:hover {color: red;
/* background: transparent - initial value; not explicitly stated */}
A:link {color: green;
background: red}
In this example, hovered over unvisited links will be red in color, even though :hover has lower
specificity than A:link
and even though it precedes it for the order sort. They will
also have a red background, since no value is explicitly stated on :hover, so :link provides the
value.
:active
:hover
vs. :active
These are sorted as above, :hover
as :hover:active, :active as it is.
:active
vs. :link
and :visited
These are sorted as above, :active as :active:link or :active:visited, :link and :visited as they are.
This is wrong, since correct at CSS 1 would be to apply the states as mutually exclusive.
A:active
applied to A:focus
:active
is incorrectly applied to tabbed-to links (not a major problem).
This means that although IE 4's link formatting is buggy, it is possible to use the bugs to achieve what you want. For example, it is possible to use the bugs to make distinctions between hovered over unvisited and visited links, etc. The temptation to exploit this is inevitable, but you should take care to ensure that your links will look O.K. in future compliant browsers.
<A>
) pseudo-classesThe CSS 2 specification permits this: A:link:hover
. IE 4 treats this, which is
invalid at CSS 1, buggily, ignoring the first of the pseudo-classes (in this example, it would be
applied as if it just said A:hover
).
Equally, it applies :link:visited
as :visited
and so on. Although I
would not encourage invalid CSS, you could take advantage of this to exclude Opera and Netscape
from link styling, subject only to the warning that Opera will apply
:link:link
(or any where both are the same), although it will not apply
:link:visited
.
ID
sIt treats id
s as case insensitive, whereas the HTML specification states that they
are case sensitive.
CLASS
esIt treats class
es as case insensitive, whereas the HTML specification states that
they are case sensitive.
class
es destroyedAlthough IE 4 does not support the use of multiple classes (e.g., <P class="one
two">
; matched by P.one.two
), it does manage to do a fine job of destroying
them, by interpreting multiple classes thus: ignore all but the last class, which is applied. E.g.,
P.one.two
would be parsed as P.two
.
If you include Unicode characters 162-177 in classes, which are valid, IE 4 will not apply the class. Furthermore, tokens solely comprised of such characters (or indeed other (truly) invalid characters) will destroy the ruleset, applying its content to every element on the page.
:first-line
IE 4 does not support :first-line.
:first-line
IE 4 does not support :first-letter.
The CSS spec permits the use of the backslash for referring to special characters and the like, but IE 4 doesn't support any of these uses. This means that you should avoid using the backslash, unless to eliminate IE from your CSS.
simple_selector
In CSS, comments are valid anywhere between tokens, but IE 4 does not support them inside simple
selectors (i.e., it doesn't support them in P/* comment here*/.class
).
@import
rulesIn addition, it does not support them in @import
rules, ignoring the import if used
therein.
*
IE 4 has severe difficulties when you close the comment with **/
(or
***/
, or more *
s), instead of */
, ignoring the rest of the style
sheet. As a result, you must avoid closing the comment with **/
.
IE 4 will ignore declarations that have comments immediately following the property (e.g.,
color/* comment */ : red
).
IE 4 will ignore selectors that have a comment immediately after the selector (e.g., P/* */{color: red}), applying them as HTML {declarations} (due to another parsing bug, explained in part 2 of this bug guide). For example, this example would be applied as HTML {color: red}. This is avoided by preceding them by a space.
Try the following piece of code:
P {font-size: 100px;
line-height: 1.15;}
<P>
Hello
</P>
<P>
Hello
</P>
Change the line-height to 115px, and reload.
Next, change the line-height to 1.15em and reload again.
Next, change the line-height to 2.3ex and reload again.
Next, change the line-height to 115% and reload again.
All the values are different, except the 115% is equivalent to the 2.3ex, which is equivalent to the px value.
Assuming the px value to be accurate (which it should be, given that IE 4 allows pixel-perfect line-heights), here is a list of the values that are applied to the buggy units.
Unit | Value |
---|---|
Em | 110px (= 1.1em) |
<number> | 120px (= 1.2) |
A little further poking around reveals that this is a bug with IE 4's rounding - it uses different rounding routines for different units. Thus:
Unit | Rounding employed |
---|---|
% | N/A |
Em | Discard all decimal places following the first |
<number> | Round to the nearest decimal place, .05 rounding up. |
ex | Discard all decimal places following the first |
The ex doesn't work and isn't usable (as is the case with all web browsers released to date).
One ex is equal to the x-height of the element's font. This allows authors to specify lengths that are proportionate to the apparent ('real') size of the font, rather than to the font-size measurement.
Internet Explorer, in common with most browsers, applies 1 ex as half of font-size (which is wrong, since in some fonts it is more than half, while in others it can be as little as a third of it). This bug renders the ex useless.
See above.
According to the CSS specification, where there is no matching glyph for the character
requested, a font that does include the glyph should be used instead. While IE applies this for
character references (such as "
, or C
), it does not do
so for un-referenced characters, instead applying the glyph that is in the same position in that
font as the requested glyph normally would be. Thus <SPAN
style="WingDings">H</SPAN>
should result in a H, and WingDings should not be used
since it doesn't contain any H's. This means that you should be wary of specifying fonts that lack
the appropriate glyph for unescaped characters.
lighter
This is buggy, not applying the next lightest font; for example, MS Arial, which contains weights corresponding to 100-500, 600, 700-800 and 900, gives a weight of 600 from an inherited value of 900 in IE 4 and thence (correctly) to 100-500.
bolder
This is buggy, not applying the next boldest font; for example, MS Arial, which contains weights corresponding to 100-500, 600, 700-800 and 900, gives a weight of 700-800 from an inherited value of 100-500 in IE 4 and thence (correctly) to 900.
Although the CSS specification states that medium
is the initial value of
font-size
, IE does not apply this, and makes small the initial value. This is a shame
because IE's implementation of the font size keywords is otherwise excellent, but this one bug
ruins it.
Smaller is bizarrely buggy - font-size: smaller with an inherited value of 16 pixels (a typical value) results in a value of 16 pixels, whereas if smaller is applied to that inherited, 13 pixels results. This does not stop you using larger however, which is perfectly (and sensibly) implemented.
When specified on monospaced elements, relative font sizes are related to the default, rather than to the inherited value. For example, font-size: 100%, which should give the monospaced elements the same font size as the parent element, in fact gives them 100% of the default value.
Font-style: oblique is applied as font-style: italic, which is wrong - if one wanted oblique, failing which italic, one should write font-style: italic; font-style: oblique.
Font-variant: small-caps doesn't apply a small-caps font, even if one is available, but is applied as text-transform: uppercase and a smaller font.
If font-variant: normal is applied to text that has been text-transformed, the text-transform is ignored. Note that this does not apply to inherited font-variant: normal, but it does apply to inherited text-transform. E.g., it applies to:
<div style="text-transform: capitalize">
<p style="font-variant: normal">
Test text
</p>
</div>
But not to:
<div style="font-variant: normal">
<p style="text-transform: capitalize">
Test text
</p>
</div>
When a user font is specified (e.g., font: caption), it should reset all font values to normal, and should also reset line-height, and if the OS doesn't have values for these for the UI font, they should be set to their initial value. In IE, they only reset the values set by the OS - weight (i.e., boldness), style (i.e., italicity), size and family, but do not reset line-height or font-variant. This means that you should specify line-height explicitly, and must specify font-variant explicitly if you use font-variant: small-caps.
IE only supports the hyphenated user fonts (viz. small-caption, status-bar, message-box) if you (illegally) omit the hyphen.
While this is definitely a bug (albeit one caused by a change in CSS), it demonstrates the importance of consistency - CSS does not hyphenate user colors, but it does hyphenate user fonts; that there should be some confusion is hardly surprising. This doesn't actually cause any problems at all, provided you do this:
P {font: smallcaption; /* For IE 4 */
font: small-caption; /* For compliant UAs - doesn't mess up IE, since it interprets it as a
font-family, but correctly ignores the declaration since font-size (required, else invalid) is
omitted)
}
When an image is inline, it should increase the line-height
if needed to fit it on
the line, but it should not decrease it. IE ignores this, and all line boxes that have inline
images automatically and irreversably have line-height: normal
.
line-height
with large fontsThere is a serious bug with %. Try this:
<style>
P {margin: 0; /* Makes no difference, nor does whether the text is in one P split over several
lines or several; only included to illustrate the point /*
font-size: 200px;
line-height: 110%;
}
</style>
</head>
<body>
<p>
Hello
</p>
<p>
Hello
</p>
Now change the line-height
to 220px. You will find that the
line-height
increases dramatically. Some tinkering produces the startling revelation that
the line-height
that this applies is 179px
. To make matters worse, it
seems that the greater the font-size
, the smaller the line-height
it
applies, relatively speaking, with the same code at 300px resulting in unsightly overlapping.
This means that % should be avoided on font-size
>162px (note that the bug
applies whether font-size
is specified in px or in any other units - it would apply
if, for example, a size was specified in inches that corresponded to this value).
normal
Normal
does not apply a constant <number>, as it probably should. For
example, given font-size: 10px
, line-height: normal
is applied as 1.275
<= n < 1.325, whereas font-size: 20px
applies 1.1375 <= n < 1.1625. This
isn't noted as a bug because the spec doesn't say that this wrong; however, I think it is.
IE 4 doesn't calculate the size of line boxes in the correct manner - it makes them equal in size to the largest value for line-height in the line box, whereas correct would be to make it from the top of the top inline box to the bottom of the bottom one.
Although this is technically a bug, it is a better approach than the 'correct' one, and as such should not be changed - it certainly won't cause anyone any problems.
Where a text-indent is specified that exceeds the element's width, IE 4 increases the padding-right of the element to compensate. This is unlikely to be a problem since text-indents do not typically exceed a few percent.
This doesn't work on BODY. E.g.:
<BODY>
<H1>A heading</H1>
A paragraph.
This means that if you wish to apply text-indent to such paragraphs, you will have to enclose them in P tags.
In addition to text-indent not being applied to BODY, it is not inherited from it either.
These are interpreted relative to the width of BODY (N.B., not of the viewport), not to the containing block as the spec states (but I think is wrong and should be the width of the element itself).
Text-decoration is inherited rather than applied (as the spec states) as though descendant elements should have the text-decoration of their parent (i.e., the same color, thickness, etc.). This means that the text-decoration will be the color of the descendant rather than of the ancestor, and also that text-decoration: none will work on descendant elements to suppress the ancestor's text-decoration, which is clearly a nonsense.
IE incorrectly 'inherits' text-decoration. For example, P {text-decoration: underline} P.class {text-decoration: line-through} would apply both of them to the P.class.
This bug, although highly unlikely to occur, can be avoided as follows:
P {text-decoration: whatever}
P.class {text-decoration: whatever-else}
Becomes:
P {text-decoration: whatever}
P.class {text-decoration: none}
P.class {text-decoration: whatever-else}
N.B., not:
P.class {text-decoration: none;
text-decoration: whatever-else}
This bug (and its workaround) would also apply where an element had both a class and an id, and they had differing text-decorations.
IE 4 inherits text-decoration to block elements, whereas the CSS spec states that is only inherited to inline descendants.
This doesn't work.
IE 4 does not ignore text-decoration: blink correctly. For example, given text-decoration: underline; text-decoration: blink, it should ignore the blink declaration because it doesn't support it and apply the underline, but it doesn't, applying no text-decoration at all. Note that this is in a sense non-serious because it is highly unlikely that anyone would have this kind of declaration anyway. This bug also means future values of text-decoration will probably cause problems.
IE 4 fails to underline the alt text of images.
This doesn't work.
Sub and super are the only supported values on text.
This aligns the middle of the element's box with the baseline of the parent box, not the baseline plus half the x-height as it should.
Not supported on images or form elements.
Only aligns with the baseline, not the bottom as it should.
IE 4 does not support vertical-align lengths or percentages.
white-space
White-space doesn't work.
IE 4 only draws backgrounds to the right and down, meaning that when background-position has been set (unless background-repeat is set to no-repeat, or it is set to repeat-x with the only positive background-position offset set on the y-value, or it is set to repeat-y with the only positive background-position set on the x-value, the background will only be drawn over part of the area that it should be drawn over. To give some examples that will be wrongly rendered:
BODY {
background: 50% 50% url(back.gif);
}
BODY {
background: 50% 0% url(back.gif) repeat-x;
}
BODY {
background: 0% 50% url(back.gif) repeat-y;
}
And some that will be correctly rendered:
BODY {
background: -10% -10% url(back.gif);
}
BODY {
background: 0% 10% repeat-x url(back.gif);
}
BODY {
background: 10% 0% repeat-y url(back.gif);
}
BODY {
background: 5cm 2cm url(back.gif) no-repeat;
}
Margins and padding don't work on inline text elements, but margins (not padding) do work on IMG, and both work on FORM elements.
Although the hspace and vspace HTML attributes (valid on the OBJECT and IMG elements) should be equivalenced by the margin properties, in IE 4 they are not, being applied in addition to the margin rather than instead of it.
Padding is not applied to empty elements.
margin-bottom
If you specify % on margin-top
or margin-bottom
, it should relate to
the width of the containing block (i.e., the width of the nearest block-level ancestor), but IE 4
doesn't apply this, instead relating it to the height of the viewport.
Margin-left
and margin-right
% on margin-left
and margin-right
relate to the width of the
containing block, but in IE 4 they relate to the width of the viewport.
If you set margins to auto, they are replaced with 0, which is wrong when both
margin-left
and margin-right
are auto or when either margin-left or
margin-right is set to auto and width is set to a value other than auto, or when margin-right is
not 0 and margin-left is auto.
If you set a negative margin right on an element and it causes its right edge to go to the right of the right edge of the canvas, the canvas will not be extended by adding or extending a scroll bar, and hence the content will be cut off.
If width is set via margin-right
(e.g., margin-right
: 50% to set
width: 50%), descendant elements will treat the width of the element as 100% for the purpose of
width in %. For example:
<DIV style="margin-right: 50%">
<DIV style="width: 200%">
</DIV>
</DIV>
Would result in a width of the inner element of 200% of normal, not 100% as it should be.
margin-right
not ignored when width setWhen width is set, since IE 4 doesn't support auto, it should ignore margin-right
,
setting it to such a value as to make it fit the containing block, but doesn't, applying it
regardless.
Padding-left
and padding-right
Although percentages on padding-left and padding-right should relate to the width of the containing block, in IE 4, they relate to the width of the viewport. Strangely, they do relate to the width of the containing block on padding-top and padding-bottom.
When a DIV has padding-top
or padding-bottom
set on it, its first and
last child's backgrounds will color in the padding. For example:
<div style="padding: 2em;">
<P style="background: red;">
</P>
<P style="background: green;">
</P>
</div>
Would set DIV's padding-top
to red, and its padding-top
to green. This
is of zero consequence unless either element has a border.
Note that the right and left padding would (correctly) be transparent.
Borders are unusable on BODY, being applied outside of the scroll bar, thus meaning that the border is drawn outside of the scroll bar.
As a result, they should be avoided.
According to the CSS spec, margins are outside of borders. IE 4 does not apply this, applying margins inside borders on BODY.
Borders are badly broken on HTML as well, though in a different way. They are only applied when BODY does not have a border (i.e., BODY's border is renderd on top), and the rest of the time they are applied in a buggy way that destroys the page.
As a result, they should be avoided.
If an element that has a border and margin is inside an element with width set on it, it is given extra padding, the margin is applied twice, once as margin and secondly as padding (in addition to the padding property). E.g.:
P {margin-left: 5%;
border: solid;
padding: 0}
DIV {
}
<DIV>
<P>
Hello
</P>
</DIV>
Try this code, and then add width: 300px to the DIV element. This will cause unsuppresable padding inside the P.
IE 4 does not support borders on inline non-replaced elements; however, it does support them on replaced elements.
Where a border width is set and width is explicitly set, it is deducted from the element's width, rather than added to the margin-right. Whilst this is not likely to be significant when you have a thin border, it will be when you set a big one, as is likely with 3d borders.
Because IE applies the 3D border styles by applying a darker section, all of the following border styles will appear as solid when the border color is black or very dark:
The dotted and dashed border styles are not supported, being rendered as solid
.
Because this page would otherwise be a very large download, you will have to click here to go on to the next section, which considers Internet Explorer's support for tables, width, height, floats, etc.
Copyright © RichInStyle.com 2000; all rights reserved. See copyright document for terms of use. Please visit Bukit Lawang flood appeal.