Anda di halaman 1dari 6

How To Attack An Internet Explorer (Win) Display Bug

By: John Gallant , Holly Bergevin ,

It's a well-known fact that the Internet Explorer (Win) browser has a wide variety of display bugs.
While it may seem satisfying to badmouth that browser, IE is by far the most popular browser on the
web, so whining about its drawbacks is not going to help very much.

Sadly, many authors who desire to make the switch to table-less design begin with high hopes, only to
have those hopes dashed by what is sometimes known as the "Explorer bug suite." Some of those bugs
are not "bugs" at all, but rather misapplications of the W3C standards. Although a full understanding of
how IE "gets it wrong" is a full-time job, it is possible to get by with a modicum of bug fixing tools,
which is what this article is going to teach you. All ready? Let's go!

Clearing The Decks

Before any bug fixing can be done, it is necessary to make sure that the problem really is a bug, and not
just improper coding, or a failure to understand how CSS positioning works. As a primer on bug hunting
you should read Debugging CSS, the Easy Way
(http://www.communitymx.com/abstract.cfm?cid=A33F8E6B1608B4E6) , which details this preliminary phase
in detail. It also describes how to create a "minimal test case," which can greatly simplify the issues to be
addressed. But just making such a test case is time consuming, and job pressures often prevent people
from going this route. Still, it is a highly recommended method to use, and one we put into practice
regularly.

Even when a test case is made, it is not always easy to just look and say, "Aha! That's it!" While it's true
that having extensive bug knowledge does help in locating a problem, many busy coders don't have time
to devote to studying bugs at length.

However, once a minimal test case is prepared, there are usually very few page elements remaining to
consider, and it becomes possible to fire "magic bullets" at various elements in an attempt to solve the
problem. Be aware that these fixes are useless against any proper browser behaviors that are mistaken for
bugs by CSS newcomers. It's up to you to have a firm grasp on the basics of CSS coding. You can read
up on the subject in the following articles:

CSS: An Introduction (http://www.communitymx.com/abstract.cfm?cid=EA87013F0E8B6A50)


Flowing and Positioning: Two Page Models (http://www.communitymx.com/abstract.cfm?cid=EA1A82A6F65A33F5)
Float: The Theory (http://www.communitymx.com/abstract.cfm?cid=A46708877E1AC008)

The fixes to be discussed are also worthless against any of the deliberate CSS specification violations

1 of 6
that occur in IE/Win. To learn about the major non-bug IE misapplications, read:

The Box Model Problem (http://www.communitymx.com/abstract.cfm?cid=E0989953B6F20B41)


Float: The Bugs (part one) (http://www.communitymx.com/abstract.cfm?cid=AF85B1B881347F29)
Float: The Bugs (part two) (http://www.communitymx.com/abstract.cfm?cid=A92AB1E766FD5416)
Float: The Bugs (part three) (http://www.communitymx.com/abstract.cfm?cid=A8162CEF9AA1BF53)

One special problem worth pointing out is the way in which floats are "cleared," as described in the
Float: The Theory article mentioned above. IE will usually (wrongly) allow a container to enclose a
nested float, even when no clearing element is present. This creates the impression that the non-IE
browsers are incorrect, when the real offender is IE/Win. Don't be fooled in this way as have so many
others.

You may also find useful information on many smaller display problems in the Common Coding
Problems series of articles here at CMX. (A search for the terms Common Coding Problems will get you
a list of all the articles in the series.) Assuming these issues are well understood or are not relevant to
your current problem, let's proceed to look at the bug fixing methods themselves, shall we?

{ position: relative }

This "magic bullet" was the first one discovered, back in December of 2001 by a certain author who's
initials happen to be "BJ" (ahem). Anyway, the issue then was a technique developed by Eric Meyer
here (http://www.meyerweb.com/eric/css/edge/boxpunch/demo.html) , which appears to "punch" a box out of
the corner of another box.

Eric's method involves floating a box into the upper left corner of a text containing element, and then
using 1px negative top and left margins, which has the effect of "pulling" the float up and to the left by
1px. This allows the float to cover, or obscure, the 1px borders on the larger containing box in that area.
Then, the float gets a bottom and right border that seems to be a part of the overall border. Neat.

The problem with this method was that Explorer for Windows was failing to obscure the corner of the
large element's border properly, ruining the intended "boxpunch" effect. It seems that IE/Win has a
problem when an element is negatively margined out of the parent box surrounding it. The portion still
within the parent "container" is visible, but any part that goes beyond the inner edge of the container's
border just vanishes!

It turns out that applying a simple {position: relative;} to the negatively margined inner box causes the
missing portions to magically reappear. Why? Well, moving right along... Seriously, no one knows why
this happens, except perhaps the Microsoft engineers, and they aren't talking. Suffice to say it does work.

Soon, this fix was found to work on other IE bugs as well, specifically the Peekaboo Bug
(http://www.communitymx.com/abstract.cfm?cid=A47F91175DB7863B) in IE6 (look on the third page of the
article). We'll get back to the Peekaboo bug in just a little while.

Another primary use for this fix is occasioned when a floated image is in a container and either the
container or the floated image has been made "relative." In that case, the floated image can and will
"hide" behind any background that may be placed on the outer container element. Removing the relative
positioning or making both elements relative will bring the floated image "up front," allowing it to be
seen.

2 of 6
Problems With the "Relative" fix

Usually this fix will not adversely affect other browsers, but as just explained, in the case of floated
images it may be necessary to perform a "double" fix, using {position: relative;} twice. Figuring out
where to apply this fix is not usually a problem. Just stick it on one element at a time and check to see if
the bug is zapped. In the event that this fix does cause trouble in other browsers, you may hide this fix
from them, feeding it only to IE/Win via the methods outlined in the next section.

Dimensional Bug Fixing

A very large percentage of IE/Win bugs are triggered by the lack of any stated dimensions on elements
that contain nested floats. In other words, if you have a box without either a width or a height, and nest
one or more floats inside, some very weird display bugs may declare themselves. Such bugs can happen
without floats, but are far rarer than the float variety.

The Peekaboo Bug (http://www.communitymx.com/abstract.cfm?cid=A47F91175DB7863B) falls into this


"dimensional bug" class, as does the Escaping Floats Bug
(http://www.communitymx.com/abstract.cfm?cid=AECCDCBE38B8A02E) . There's the Peekaboo Bug again! So
this hard-shelled devil is vulnerable to both the "relative" fix and the dimensional fix! Very interesting.
Such is the nature of IE bug "science."

This sort of dimension-related IE buggy-ness has been known for several years, but simply knowing
wasn't good enough. Very often, it is undesirable to apply a dimension to the buggy box. Using a height
is usually unacceptable, since having the height be the default value of auto allows the content in the box
to determine that box's displayed vertical height. If you give the box a defined height, it may not match
the height of the content, particularly if text is involved and the user changes the browser text sizing.

A width may sometimes be used, but often the page design calls for the problem box to be "liquid," so as
to automatically widen or narrow in response to changes in window size. Yes, a percentage width can
also do this, but what if the box is a center column and needs to have pixel sized side columns next to it?
It is impossible to have a percentage width on a box and pixel sized margins on that same box, because
no one can predict how rigid pixels may compare against fluid percentages.

Clearly, using width as a bug-fixing dimension is less than satisfactory. There seemed no clean way to
accomplish the task at hand, and yet by a strange quirk of fate, the Explorer browser itself came to the
rescue.

The Expanding Box Trick

CSS gurus have known for a long time that when IE/Win sees that a box has a stated dimension that is
not large enough to enclose the content of that box, the browser will wrongly enlarge the width of the
box to accommodate unbreakable lines, such as long URLs. IE/Win will also extend the height of a box
so that its content does not overflow the bottom border of the box. Browsers that more closely follow the
W3C specifications let the extra content protrude beyond the height or width controlled box.

3 of 6
The Holly Hack

Since IE/Win will misbehave in this manner, when a dimension is needed to fix a float bug, a very small
height, such as {height: 1%}, can be applied to the float container, and IE/Win will just make the box
taller anyway. Thus, a small height does not change the appearance of the box, but IE seems to think the
box is now "dimensioned," and so our magic bullet strikes home. Scratch one bug.

Details of The Hack

Since other browsers don't have the bug, and more importantly, don't wrongly expand height-defined
boxes, this bug-fixing height should be hidden from browsers other than IE/Win. It is not necessary to
hide this fix from earlier versions of IE/Win, since even though they don't have the Peekaboo Bug, they
do have other dimension based bugs, and they all do the expansion trick. However, IE5/Mac doesn't
incorrectly expand boxes, so letting that browser see the small height is sure to damage its display. Thus,
the height needs to be hidden from it, as well as the other, non-IE browsers.

The following code is an instance of the Holly hack. Primarily, the Holly hack consists of a set of hiding
methods wrapped around that 1% height, which is the key to the hack. Remember, the whole idea is to let
IE/Win and only IE/Win see that height and apply it to the buggy box.

/* Hi des fr om IE5 -ma c \*/


* htm l . buggyb ox {he igh t: 1%; }
/* En d h ide fr om IE5 -ma c * /

Code Block 1

Two Hacks in One: The first line of code is a CSS comment with an "escape" (colored red) just before
the comment closing tag. The presence of that escape character causes IE5/Mac to ignore the closing tag
of the comment, and think that the comment is still active. Thus, it ignores everything until it sees what it
thinks is a correct CSS comment closing tag. The last line of the hack is a normal CSS comment, and its
closing tag is what lets IE5/Mac begin parsing code again. We generally refer to these two lines (the top
and bottom in the above code box) as the "Mac-hack," but it is also referred to as a "comment-backslash
hack."

The second, or middle line, has, in this example, three items separated by descendant combinators, which
are the spaces you can see, and then the height property within curly brackets. First item is a universal
selector or star, *, which selects any element, followed by html (both also in red), followed by the
element suspected to have the bug. The above code selects an element with the class attribute of
buggybox that is a descendant of an html element, (which will always be true), when html itself is a
descendant of any element (*), and applies a {height: 1%} to that element, in this case, .buggybox.

It so happens that all IE browsers, both Win and Mac, recognize an invisible and mysterious wrapper
element around <html>. The use of the universal selector preceding html, also known as the Tan Hack
(http://www.info.com.ph/~etan/w3pantheon/style/starhtmlbug.html) (or Star HTML Selector Bug), works in IE
browsers and nowhere else. Thus, the reason for using the "Mac-hack" is to prevent IE5/Mac from seeing
this height just as other browsers are, because it does not wrongly enlarge the box like IE/Win, but it does
read the Tan hack.

4 of 6
Note that the element to be given the height need not be classed. Any valid selector may be inserted
instead of .buggybox, and even entire strings using descendant combinators may be used there. What
really matters is that * html must always precede whatever target element is to be fixed, and that the *
and html have a space between them, followed by another space, and then the target element.

There are other methods that can be employed to both give IE/Win the height-fix it needs, and not give it
to other browsers. One method is to set the small height in the regular selector for the element and then
override that height with the auto value in a following selector that uses a child combinator, >, which
IE/Win browsers do not recognize. This requires knowing the direct parent of the buggy box. It is not a
good idea to use spaces around the child combinator, as this can cause bugs.

Another method is to use the Tan hack to hide the height from browsers other than IE, and then override
that height for IE5/Mac only, using a modified Mac-version of the Tan hack, which again uses the child
combinator to prevent IE/Win from reading the redefined value. The Mac-version also requires an escape
character (a backslash, \) to be used in each property name included in a ruleset to prevent IE5/Win from
reading the rules. In the Mac-modified version of the Tan hack, the child combinator replaces the
descendant combinator normally used between the star and html. This is shown in red in the last line
below. The escape (the backslash character, also in red) is used in the height property. Both of the
alternate methods just described are shown in the following code block.

Ch ild Co mbi nat or Ove rri de Met hod


.b ugg ybo x { height : 1 %;}
#p are ntE lement> .b uggybo x { height : a uto ;}

Mac-m odi fied T an Hac k M eth od


* htm l . buggyb ox {he igh t: 1%; } / * f or IE/ Win */
*> htm l . buggyb ox {he\ig ht: au to; } / * f or IE5/Mac */

Code Block 2

Which method should you choose? Well, as with most everything CSS, it depends. Of the three options
presented, the one we would be least likely to use is the Child Combinator Override Method. We prefer
to have the original selector for an element contain the correct value for the properties defined within,
and use a hack, or filter, as they are sometimes called, to provide alternate values for IE/Win. The other
two methods can come down to a matter of preference.

Note: The Child Combinator Override Method is our name for the method described in Code Block 2 above. As far as
we know, there is currently no commonly used name for this method, or the one using the Mac-modified version of the
Tan hack. Also be aware that if a future version of IE/Win finally does support the child combinator, this hack may
backfire by letting IE/Win see the "wrong" height value, depending on what changes actually occur in that browser.

Trick Shooting

While having a "minimal test case" to try these fixes on is the best way, it is sometimes possible for a
CSS coder to skip that step and just apply them directly to parts of a big convoluted page in the hope of
"getting lucky." This approach can be problematic for newbies however, because what may look like a
bug is often actually correct behavior, or an IE/Win specification violation. A good rule of thumb is to
compare the display of a suspected IE/Win bug to the display in Opera 7 and a Mozilla based browser. If
both these non-IE browsers look good then it's a fair bet you are seeing an IE bug or misbehavior. Telling
these apart is another matter, requiring knowledge of the IE Float model, the IE Box model, the IE 3px

5 of 6
problem, and occasionally other issues as well.

These two "magic bullets" can work wonders, enabling authors to utilize many layouts previously out of
reach due to IE bugs. They are by no means cure-alls, though they may seem as such at times, and they
are certainly no substitute for good coding practices. While there are other fixes not detailed here, the
ones we have described are the primary weapons in use today for zapping bugs in complex table-less
designs. One recent and very tricky float layout (http://www.positioniseverything.net/piefecta-rigid.html)
employs as many as eight Holly hacks to force compliance from "that" browser. Bang! Bang!

Keywords
IE bugs, CSS bugs, bug, float bug, Peekaboo bug, Escaping floats bug, Internet Explorer, position
relative, holly hack, tan hack, mac-hack, hacks, descendant combinator, child combinator, universal
selector, Star HTML

6 of 6

Anda mungkin juga menyukai