Web DevCenter    
 Published on Web DevCenter (http://www.oreillynet.com/javascript/)
 See this if you're having trouble printing code examples


CSS Hints for Internet Explorer 5

by Peter-Paul Koch and Apple Developer Connection
11/15/2002

As we know all too well, the Windows and Macintosh builds of Microsoft's Internet Explorer 5 are based on different rendering engines and therefore react differently to the same HTML or CSS. This means that Web developers have to test their pages in both browsers--they can't assume that a page that works in one will work in the other.

In general, the Mac version of Explorer is more strict in its standards compliance (and supports more of the standards) while the Windows version supports more Microsoft proprietary styles and JScript methods. And the Mac version is way ahead in terms of CSS support. For example, it supports position: fixed, something the Windows browser still hasn't been able to implement.

The Mac build of IE, like most browsers, has some bugs and idiosyncrasies that can trip up unaware developers. This article describes three types of problems you're likely to see:

1. Bugs having to do with position: relative: 2. Bugs creating extra margins for elements: 3. Bugs in the implementation of the overflow declaration:

These all appear in any version of Explorer 5 for the Mac, on both Mac OS 9 and OS X.

The Commented Backslash Hack

Fortunately, Web developers have a tool for dealing with these problems. A useful CSS hack allows developers to define special styles without resorting to browser detects and separate CSS files.

Here's how it works: Explorer for the Mac interprets a backslash in a CSS comment as an escape for the next character, as if it were reading a regular expression. Taking advantage of this incorrect behavior, you can escape the end-of-comment marker (*/) so Explorer won't parse certain style declarations:

element {
   style: for Explorer on Mac
}

/*
   This is a CSS comment where the end-of-comment marker is escaped.
   The following styles are not read by Explorer
   because it thinks they are still part of this comment.
\*/

element {
   style: For all other browsers, it overrules the previous style
   declaration.
}

/*
   Another comment, now with a normal end-of-comment marker. Explorer
   sees the end of this comment as the end of the previous one.
*/

So now you can define styles for Explorer and overrule them for all other browsers. This hack can solve a number of CSS-related problems.


Bugs related to position: relative

The position property takes one of four values: static, relative, absolute or fixed. The first (static) is the default value, the last (fixed) is still not supported in Explorer for Windows. Developers frequently use position: absolute while tending to avoid position: relative.

When giving an element a relative position, the element is initially placed in the natural flow of the page and then moved to its new position (as defined by the top and left properties). For example, I styled this paragraph with a top and left of 10px, so it's slightly askew.

This effect is rarely useful. What is useful is that a relatively positioned element becomes a container for elements with position: absolute. If an element has these styles:

element {
   position: absolute;
   top: 10px;
   left: 100px;
}

...it would normally be positioned at coordinates 100,10 from the upper left corner of the browser window. But if an ancestor of this element has any position but static, the element is positioned relative to this ancestor.

So you can use an element with position: relative as a container for absolutely positioned elements.

line break
line break
Again, I've positioned this paragraph relatively. I've also absolutely positioned an em element (containing the text "This is the em") with coordinates of 100,10. These coordinates use the upper left corner of this paragraph as their reference point, not the upper left corner of the browser window, so the em is still within this paragraph. This is the em.

position: relative is occasionally used for such effects, but it also has some ugly side effects in Explorer, as you'll see below.

Incorrect inheritance of position: relative

Bug: Elements inside a relatively positioned element can incorrectly inherit their position value and their left or right properties (though not their top or bottom properties) from their parent.

Example:

div.container {
   position: relative;
   border: 1px solid #000000;
   top: 50px;
   left: 50px;
   width: 200px;
}

.testdiv {
   position: static;
   border: 1px solid #000000;
   background-color: #ffffff;
   padding: 10px;
   margin: 0px;
}

I explicitly set the <DIV>s inside the container to static. The correct rendering is shown below in a screenshot from Mozilla:

Correct Rendering Screen Shot

In Explorer 5 for Mac, though, you'd get the following rendering.

Incorrect Rendering Screen Shot

Mysteriously, Explorer moves all <DIV>s (except the first one) 50px to the right. They inherit their position (relative) and their left (50px) from their parent.

Workaround: None. Fortunately, there's not a great demand for this type of styling.

Tables and absolutely positioned elements

Bug: When placing an absolutely positioned element inside a table with an undefined (and hence static) position, Explorer always reacts as if the table has a position: relative. Its coordinates are relative to the upper left corner of the table, not the upper left corner of the page. Even explicitly giving the table a position: static doesn't help.

Example: In the screenshots below, the container element is a table, and a testdiv element is inside one of the <TD>s.

<table class="container" border=2>
   <tr>
      <td>
         Blah!
         <div class="testdiv">
            This is the test DIV in the table
         </div>
      </td>
      <td>
         Blah!
      </td>
   </tr>
</table>

.container {
   position: static;
   margin-top: 50px;
   border: 1px solid #000000;
}

.testdiv {
   position: absolute;
   top: 50px;
   left: 50px;
   border: 1px solid #000000;
   padding: 10px;
}

The testdiv should be positioned relative to the browser window, since its container, the <TABLE>, has position: static:

Opera 6 gets it right. It positions the testdiv relative to the entire browser window and pays no attention to the <TABLE>:

Correct Rendering Screen Shot

Explorer, however, positions the testdiv relative to the <TABLE>, as if the table has position: relative. It also shrinks the <DIV> so it will (more or less) fit inside the table:

Incorrect Rendering Screen Shot

(Curiously, Mozilla has the opposite bug: It never places the absolute element relative to the table, even when the table has a position: relative.)

Workaround: None. Don't place absolutely positioned elements inside tables.


Margins

Hidden margins

Bug: When placing an absolutely positioned element at the right or bottom edge of the browser window, a mysterious margin crops up that causes unwanted scrollbars.

Example:

div.container {
   height: 150px;
   width: 200px;
   position: absolute;
   right: 0px;
   border: 1px solid #000000;
   background-color: #ffffff;
}

The <DIV> appears flush against the right border. Since there is no other content on the page, no scrollbars are necessary. Mozilla positions it correctly:

Correct Rendering Screen Shot

Explorer also gets it right, but then generates an unnecessary right page margin, causing an unwanted horizontal scrollbar:

Correct Rendering Screen Shot with Extra Margin

The problem is an extra 15px right margin of the <DIV>, which is exactly the space a scrollbar takes up. Still, it's not easy to understand which scrollbar should be placed in this margin. The relation (if any) of this bug to incorrect treatment of scrollbar space is not clear.

Workaround: Give the element a right of 15px and a negative right margin of 15 pixels:

div.container {
   height: 150px;
   width: 200px;
   position: absolute;
   right: 15px;
   margin-right: -15px;
   border: 1px solid #000000;
   background-color: #ffffff;
}

Which results in:

Correct Rendering Screen Shot

The other browsers react in the same way as Explorer, so this workaround gives few cross-browser compatibility problems (except for Mozilla on Windows 2000, which may sometimes show a slight margin of 1px).

The same bug can appear when positioning an element at the bottom of the browser window. In that case, margin-bottom should be set to -15px.

Margins below scrollbars

The second margin bug is clearly related to scrollbars. Unfortunately, it doesn't appear all the time, just most of the time. In about 10-20% of the cases, Explorer interprets the styles correctly, although a reload may change that.

Bug: Explorer incorrectly sees the space below a scrollbar as belonging to the canvas. Content of the page may spill below the vertical scrollbar, causing an unwanted horizontal scrollbar to appear.

Example:

body {
   margin: 0px;
   padding: 0px;
   font: 12px helvetica;
}

div.container {
   height: 150px;
   width: 100%;
   overflow: auto;
   -moz-box-sizing: border-box;
}

p {
   border: 1px solid #000000;
}

I assigned the container <DIV> a height of 150px, a width of 100%, and an overflow: auto to create scrollbars if necessary. The -moz-box-sizing is for evading box model problems in Mozilla.

Unless instructed otherwise, <P> tags always take 100% of the available width, so they stretch across the entire <DIV>. Since there are slightly too many <P>s for the box to contain, it gets a scrollbar. Now the <P>s ought to stretch from the left margin of the <DIV> to the left edge of the scrollbar.

In Mozilla, these styles have the desired effect:

Correct Rendering Screen Shot

In Explorer, however, this happens:

Incorrect Rendering Screen Shot

The <P>s stretch beyond the vertical scrollbar. Since part of the content of the page is now hidden by the vertical scrollbar, Explorer also creates a horizontal scrollbar.

Workaround: The basic solution is to add a padding-right of 16 pixels to the <DIV>:

div.container {
   height: 150px;
   width: 100%;
   overflow: auto;
   -moz-box-sizing: border-box;
   padding-right: 16px;
}

We need to hide this extra padding from the other browsers, though. Fortunately, the commented backslash hack allows us to restrict our definition of padding-right to just Explorer on the Mac:

div.container {
   height: 150px;
   width: 100%;
   overflow: auto;
   -moz-box-sizing: border-box;
   padding-right: 16px;
}

/* Commented backslash hack \*/

div.container {padding-right: 0px;}

/* End hack */

Now Explorer has a 16px padding-right while all other browsers have a 0px padding-right. The paragraphs stretch to the left edge of the scrollbar, not underneath it. The horizontal scrollbar for the <DIV> is no longer necessary and disappears.

The bad news is that this causes two new unwanted effects to appear:

The scrollbar for the entire page is again caused by an extra margin of 15px. Adding the margin-right hack solves the problem:

div.container {
   height: 150px;
   width: 100%;
   overflow: auto;
   -moz-box-sizing: border-box;
   padding-right: 16px;
   margin-right: -15px;
}

And the results:

Partially Corrected Explorer Screen Shot

Unfortunately, you still might have problems with the first paragraph. The first block-level element is not affected by the margin bug. As the screenshots show, the first paragraph doesn't stretch below the horizontal scrollbar, and the padding-right causes an unwanted gap. But this (lack of a) problem isn't consistent. Most of the time, the first paragraph behaves as it should, but sometimes it doesn't.

There is a solution for Explorer 5.2 for Mac OS X, but it doesn't work quite as well on the OS 9 version. The trick is to give the first child of the <DIV> a margin-right of -16px:

div.container>:first-child {
   margin-right: -16px;
}

...and then once again overrule this style for any other browsers by using the commented backslash hack. So the complete CSS becomes:


div.container {
   height: 150px;
   width: 100%;
   overflow: auto;
   -moz-box-sizing: border-box;
   padding-right: 16px;
   margin-right: -15px;
}

div.container>:first-child {
   margin-right: -16px;
}

/* Commented backslash hack \*/

div.container {padding-right: 0px;}

div.container>:first-child {
   margin-right: 0px;
}

/* End hack */

This usually solves it:

Corrected Explorer Screen Shot

Again, this whole series of bugs is somewhat flighty. Sometimes these CSS hacks simply won't work.

Reverse inheritance of margin-bottom

Bug: When placing a <P> inside a <DIV>, the <DIV> "reverse inherits" the margin-bottom of the paragraph. Result: a too large margin below the <DIV>.

Example:

div.container {
   height: 100px;
   width: 90%;
   border: 1px solid #000000;
   margin: 0px;
}

p {
   margin-top: 0px;
   font-size: 20px;
   border: 1px solid #000000;
}

These styles ought to look like this (as rendered in Mozilla). The first <P> outside the <DIV> is flush against the bottom border of the <DIV>.

Correct Rendering Screen Shot

In Explorer, however, the <DIV> reverse inherits the margin-bottom of the last <P> which causes an unwanted gap. The actual margin depends on the font size used in the <P>:

Incorrect Explorer Rendering Screen Shot

Workaround: Set the margin-bottom of the <P> to 0px.

Overflow

The overflow declaration defines what happens with content that overflows an element. If an element has a fixed width and height but the content doesn't fit into this defined area, three things can happen:

  1. With overflow: visible, the content spills out of the box.
  2. With overflow: hidden, the content that doesn't fit into the box is completely hidden and not accessible to the user.
  3. With overflow: auto, the box generates scrollbars if necessary. This style was used in the previous code example.

The fourth value, overflow: scroll, causes the element to always show scrollbars, regardless of whether they're needed. Web developers rarely find a use for this.

Overflowing content not clipped

Bug: When giving an element an overflow of anything but visible, Explorer doesn't clip the content of the element. Instead, the content is still present (though invisible) on the page and may create scrollbars.

Example: If we add some more paragraphs to the 'Hidden margins' code example, an unnecessary scrollbar again appears - this time a vertical one for the entire page:

Incorrect Explorer Rendering Screen Shot

The extra content of the <DIV> now overflows the entire page and creates a scrollbar, even though the overflow: auto declaration should hide this content until the user scrolls the <DIV>. (Also note that the right margin of the first paragraph goes haywire again. A very nasty bug, this one.)

Workaround: Give the body an overflow: hidden. The downside is that this workaround causes the next bug to appear.

Propagation of overflow styles of the body element

Bug: When setting the overflow of a body element to scroll or hidden, the style is propagated to all subsequent pages that are loaded into the same frame or window. Note that this usually happens, but not always.

Workaround: Explicitly reset the overflow to auto in the page that is loaded into the same frame or window.

Padding of overflowing elements

Bug: When giving a padding style to an element with an overflow of anything but visible, hyperlinks within this padding are not clickable.

Example:

.container {
   width: 200px;
   height: 200px;
   overflow: auto;
   padding: 50px;
}

These styles are rendered correctly, except for the unnecessary body scrollbar caused by the previous bug:

Incorrect Explorer Rendering Screen Shot

But links inside the padding area are no longer clickable. Note that the padding is calculated from the visible edges of the container, even though the bottom padding should be invisible because it hasn't yet scrolled into view:

Incorrect Explorer Rendering Screen Shot

Workaround: Give the content of the box a margin and set the padding of the box itself to 0.

Related Reading

CSS Pocket Reference
By Eric A. Meyer


Conclusion

Internet Explorer 5 for the Mac, despite being the most standards-compatible Microsoft browser, has some CSS issues. Unfortunately, it isn't possible to relate all these bugs to a few underlying causes and thus come up with a cure-all.

The best way to avoid them is to test all sites in Explorer 5. Even then, though, strange and inexplicable things will happen. Let's hope for the speedy release of Explorer 6.


Resources

Peter-Paul Koch is a freelance Web developer in Amsterdam, the Netherlands.


Return to the Web Development DevCenter.

Copyright © 2009 O'Reilly Media, Inc.