Web Information

Awful IE Bugs and Fixes

Introduction

Everyone has a story to tell when dealing with Internet Explorer. As a developer I have faced numerous bizzare problems with IE and sometimes you just want to bang your head against the wall! However, as time goes by, we slowly learn from mistakes (well, sometimes it's not our fault, it's IE!!!) and start to adapt and understand IE's weird behaviors. We have to because there is still a considerable number of IE6 users. The best practise is to continuously test your website from the start across different browsers. It's easier to fix the layout problems from the start rather than testing and fixing it in the end after thousands of lines of html and css code.

There are a lot of campaigns out there to protest against IE6. People who support it are mostly web specialists and normal users just don't seem to care. So, what we can do now? We have to continue to digging around to fix IE6 issues. But, wait for it, there is a Good and Exciting News. Based on the monthly stat from w3cschool, IE6 users have been steadily decline over a few years. Since 2006 Jan 60.3% until now 2009 Aug 13.6%. At this rate, we should able to get rid of IE6 around end of next year 2010. YES!!!

Right, Back to reality, I have listed all the problems that I have encountered before into a list for future reference. I believe this will help you shorten the times spent on debugging the layout inconsistensies in Internet explore.

1. IE6 Ghost Text Bug

Just before I wrote this article, I encountered this bug. It's so bizzare and hilarious. A piece of duplicated text came from nowhere and IE6 display it somewhere in the bottom near to the original text. I couldn't solve it, so I search for it, and BINGO, it's just another IE6 Bug.

There are quite a lot of solutions for it, but none of them work to me (I can't use some of the methods because of the complexity of the website.), so I used a really hacky method. Adding spaces next to the original text seems to solve the problem.

However, from a website called Hippy Tech Blog I found online. The reason behind it is due to the html comment tag. IE6 can't render it properly. The following is a list of solutions he suggested:

Solution
using tags around the comment.
remove the comment
in the preceding float add a style {display:inline;}
Use –ve margins on appropriate floating divs.
adding extra   (like 10 spaces) to the orginal text (the hacky way)
2. Position Relative and Overflow Hidden

I faced this problem a lot of times when preparing a jQuery tutorial, because I used overflow hidden a lot to make the desired layout.

It happens when the parent element overflow set to hidden and the child element is set to position:relative.

CSS-Trick has a good example to demonstrate this bug. position:relative and overflow in internet explorer

Solution
Add position relative to the parent element.
3. Min-Height for IE

It's simple, IE ignores min-height properties and you can use the following hack to fix it. Credit to Dustin Diaz

This solution works like a charm in IE6, Mozilla/Firefox/Gecko, Opera 7.x+, Safari1.2

Solution
view plaincopy to clipboardprint?
selector {
min-height:500px;
height:auto !important;
height:500px;
}
4. Bicubic Image Scaling

You'll love this one. Does the bad image scaling in IE bothering you? If you compared other browsers and IE, IE's rescaled image doesn't look as good as other.



Solution
view plaincopy to clipboardprint?
img { -ms-interpolation-mode: bicubic; }
5. PNG Transparency

I guess everyone knows this, but I'm going to put it here anyway just for future reference :)

So if you want to use transparent image and GIF doesn't give you the quality you want, you will need this hack for PNG. You have to be aware, if you use a PNG as background, you will not able to set the background position.

Solution
view plaincopy to clipboardprint?
img {
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(...);
}
6. IFrame Transparent Background

In firefox and safari you shouldn't encounter this problem because by default, the iframe background is set to transparent, but in IE, it doesn't. You need to use allowTransparency attribute and put the following CSS code to achieve that.

Solution
view plaincopy to clipboardprint?
/* in the iframe element */



/* in the iframe docuement, in this case content.html */
body {
background-color:transparent;
}
7. Disabled IE default Vertical Scroll bar

By default, IE displays vertical scrollbar even though the content fit nicely in the window. You can use overflow:auto to show it only when you need it.

Solution
view plaincopy to clipboardprint?
html {
overflow: auto;
}
8. :hover Pseudo Class

IE only supports :hover pseudo class for anchor element. You can achieve the same effect using jQuery hover event.

Solution
view plaincopy to clipboardprint?
/* jQuery Script */
$('#list li').hover(

function () {
$(this).addClass('color');
},

function() {
$(this).removeClass('color');
}
);


/* CSS Style */
.color {
background-color:#f00;
}

/* HTML */
  • Item 1
  • Item 2
  • Item 3
9. Box Hack Model

This is the hottest bug in IE. The basic understanding is that IE calculates width differently. Based on w3c standard, total width of an element should be

total width = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right
However, Internet Explorer calculates it without adding paddings and borders:

total width = margin-left + width + margin-right
For more details, please check out this link: Internet Explorer and the CSS box model Detailed Explanation Solution
Use the w3c use standards compliant mode. IE6 or later will calculate the width based on w3c standard, however, you will still having problem for IE5
Or, you can use CSS Hack to solve this problem. All standard compliant browsers will able to read w\\dth:180px except IE5.

view plaincopy to clipboardprint?
#content {
padding:10px;
border:1px solid;
width:200px;
w\\idth:180px;
}
10. Double Margin Bug Fix

If you have floated elements with margin left and/or right assigned, IE6 will double up the margin. Forexample, margin-left:5px will become 10px. You can solve that by adding display:inline to the floated element.

Solution
view plaincopy to clipboardprint?
div#content {
float:left;
width:200px;
margin-left:10px;

/* fix the double margin error */
display:inline;
}
Final words

Perfect Full Page Background Image

We visited this concept of re-sizeable background images before… but reader Doug Shults sent me in a link that uses a really awesome technique that I think is better than any of the previous techniques.

This technique and the above background image is credited to this site. Here is what this technique is going to accomplish:

* Fills entire page with image, no white space
* Scales image as needed
* Retains image proportions
* Image is centered on page
* Does not cause scrollbars
* Cross-browser compatible
* Isn’t some fancy shenanigans like Flash

This is a very tall order, and we are going to be pulling out all kinds of different stuff to make it happen. First of all, because the image needs to scale, a traditional CSS background-image is already disqualified. That leaves us with an inline image.
Technique #1

This inline image is going to be placed on the page inside of a bunch of wrappers, each necessary for accomplishing all our goals.




And the CSS:

* {
margin: 0;
padding: 0;
}

html, body, #bg, #bg table, #bg td {
height:100%;
width:100%;
overflow:hidden;
}

#bg {
position: fixed;
}

#bg div {
height:200%;
left:-50%;
position:absolute;
top:-50%;
width:200%;
}

#bg td {
text-align:center;
vertical-align:middle;
}

#bg img {
margin:0 auto;
min-height:50%;
min-width:50%;
}

That’s quite a little load of markup and CSS, but it does the trick very well! Just doing this alone gets the job done, but what about if we want actual content on the page. Setting that overflow to hidden on the html and body elements should scare you a little bit, as that will totally cut off any content that is below the fold on a site with no scrollbars. In order to bring back scrollable content, we’ll introduce another wrapper. This one will sit on top of the background, be the full width and height of the browser window, and set the overflow back to auto (scrollbars). Then inside of this wrapper we can put content safely.



#cont {
position:absolute;
top:0;left:0;
z-index:70;
overflow:auto;
}

.box {
margin: 0 auto;
width: 400px;
padding: 50px;
background: white;
padding-bottom:100px;
font: 14px/2.2 Georgia, Serif;
}

JavaScript Fixes

For IE 6, there is some MooTools stuff going on to fix it up

In Firefox, default “focus” is placed on the body element when the page loads. That means that pressing the space bar will scroll down the body, which would reveal some ugly white space. We can use some jQuery for a quick fix, to remove that focus and place it on a hidden element instead, removing that problem:

$(function(){
$(".box").prepend('');
$("#focus-stealer").focus();
});

The addition of fixed positioning on the #bg wrapper eliminated the space bar/scrolldown problem. CSS FTW!

IE 6 actually had the best CSS support of any browser when it first came out… SEVEN YEARS AGO. The little bugs in it’s CSS support still haunt us to this day. I still get comments from people who roundly reject any technique that doesn’t work in IE 6. While I generally refuse to pander to IE 6’s limitations, I still feel it is important to make things look right in it whenever possible. Here are that major bugs in IE that’ll get you every time:
The Box Model

This is perhaps the most common and frustrating bug of all in IE 6 and below. Let’s say you declare a box like this:

div#box {
width: 100px;
border: 2px solid black;
padding: 10px;
}

IE 6 will calculate the width of the box to be 100px.
Modern browsers will calculate the width of the box to be 124px.

This kind of discrepancy can cause HUGE layout problems. I even think the IE version makes a little bit more sense logically, but that is not how the spec was written. IE 6 can actually get it right if you are in standards-compliant mode, which is rare these days as just using an HTML 4.0 transitional doctype will trigger quirks mode and the box model problem.

I generally work around this issue by just not using padding on boxes I am using for layout. If that box has some text inside it in a

element, I’ll apply the padding it needs directly to that p element. Just side-steps the issue, but it works.


The Double Margin Bug

Using our box example from above, let’s say we need that floated to the right:

div#box {
float: right;
margin-right: 20px;
}

IE 6 will double the 20px to 40px. Again, causing potentially huge layout borks. The commonly thrown-around “fix” for this is to add “display: inline;” to the div. I’m not sure how this “fix” got so much traction, but its a bit impractical. We can’t set static widths on inline elements, now can we?

I also like to side-step this bug whenever possible. If you really need to push that box away from the right side of it’s parent element, you can likely do so by adding padding to the parent element, which is more likely to keep your grid consistent anyway. Also don’t forget about padding. This bug does not affect padding, so you can offen get away with adding padding to the side you need an achieve the same result.


No Min Widths / Min Height

Setting min-width and min-height on elements is such a natural and logical thing that it makes me tear up sometimes thinking I can’t count on them. IE 6 doesn’t just get it wrong, it just completely ignores them. Min-height is incredibly useful for something like a footer. Say your footer needs to be at least 100px tall because you are using a background image down there, but you don’t want to set a static height because you want it to grow nicely if, say, the text size is bumped up significantly. Min-height is perfect for this, but using it alone will get you no height whatsoever from IE 6. In a bizarre twist of luck, IE 6 treats the regular height property like modern browsers treat min-height, so you can use a “hack” to fix it. I call it a “hack”, because I don’t really consider it a hack since it validates just fine.


Stepdown

Normally when floating objects you can count on them lining up vertically until they break. That is, you could if you weren’t using IE 6. IE 6 appends a line break effect after each floated block element which will cause “stepdown”. The fix here is to make sure the line-height in the parent element is set to zero (0), or that the elements being floated are inline elements. More on preventing stepdown here.


No Hover States

Most modern browsers support hover states on just about any element, but not IE 6. IE 6 only support the hover pseudo-class on anchor () elements, and even then you don’t get them if your anchor doesn’t have a href attribute. The solution here is to use a proprietary fix, or just deal with not having hover states on everything you want.


No Alpha Transparent PNG Support

Kind of funny that Microsoft themselves developed the PNG format, but their own browser doesn’t natively support it (until IE 7)*. I have a whole roundup of different fixes for this. Do remember that regular non-alpha transparent PNG files work fine without any fix in IE 6, and are often better than their GIF sisters.

*Update: I was totally wrong about the Microsoft thing, no idea how that got in my head. Tom Boutell actually developed the PNG format. Thanks all!


So…

All these bugs are either fixable or side-steppable, but they will get ya if you don’t do your testing. My general philosophy is: design with the most modern techniques possible, but then just make sure it ain’t busted in older ones.

Why clean markup?

Client-side optimization is getting a lot of attention lately, but some of its basic aspects seem to go unnoticed. If you look carefully at pages on the web (even those that are supposed to be highly optimized), it’s easy to spot a good amount of redundancies, and inefficient or archaic structures in their markup. All this baggage adds extra weight to pages that are supposed to be as light as possible.
The reason to keep documents clean is not so much about faster load times, as it is about having a solid and robust foundation to build upon. Clean markup means better accessibility, easier maintenance, and good search engine visibility. Smaller size is just a property of clean documents, and another reason to keep them this way.
In this post, we’ll take a look at HTML optimization: removing some of the common markup smells; reducing document size by getting rid of redundant structures, and employing minification techniques. We’ll look at currently available minification tools, and analyze what they do wrong and right. We’ll also talk about what can be done in a future.

Markup smells

So what are the most common offenders?

1. HTML comments in scripts

One of the gross redundanies nowadays is inclusion of HTML comments — — in script blocks. There’s not much to say here, except that browsers that actually need this error-prevention measure (such as ‘95 Netscape 1.0) are pretty much extinct. Comments in scripts are just an unnecessary baggage and should be removed ferociously.

2. sections

Another often needless error-prevention measure is inclusion of CDATA blocks in SCRIPT elements:
<script type="text/javascript">
    //
  script>

It’s a noble goal that falls short in reality. While CDATA blocks are a perfectly good way to prevent XML processor from recognizing < and & as start of markup, it is only the case in true XHTML documents — those that are served with “application/xhtml+xml” content-type. Majority of the web is still served as “text/html” (since, for example, IE doesn’t understand XHTML to this date), and so is parsed as HTML by the browsers, not as XML.
Unless you’re serving documents as “application/xhtml+xml”, there’s little reason to have CDATA sections hanging around. Even if you’re planning to use xhtml in a future, it might make sense to remove unnecessary weight from the document, and only add it later, when actually needed.
And, of course, an ultimate solution here is to avoid inline scripts altogether (to take advantage of external scripts caching).

3. onclick=”…”, onmouseover=”“, etc.

There are some valid use cases for intrinsic event attributes, such as for performance reasons or to target ancient browsers (although, I’m not aware of any environment that would understand event attributes — onclick="...", and not property-based assignments — element.onclick = ...). Besides well-known reasons to avoid them, such as separation of concerns and reusability, there’s a matter of markup pollution. By moving event logic to external script, we can take advantage of that script’s caching. Event handler logic doesn’t need to be transferred to client every time document is requested.

4. onclick=”javascript:…”

An interesting confusion of javascript: pseudo protocol and intrinsic event handlers results in this redundant mix (with 106,000 (!) occurrences). The truth is that entire contents of event handler attribute become a body of a function. That function then serves as an event handler (usually, after having its scope augmented to include some or all of the ancestors and element itself). “javascript:” addition merely becomes an unnecessary label and rarely serves any purpose.

5. href=”javascript:void(0)”

Continuting with “javascript:” pseudo protocol, there’s an infamous href="javascript:void(0)" snippet, as a way to prevent default anchor behavior. This terrible practice of course makes anchor completely inacessible when Javascript is disabled/not available/errors out. It should go without saying that ideal solution is to include proper url in href, and stop default anchor behavior in event handler. If, on the other hand, anchor element is created dynamically, and is then inserted into a document (or is hidden initially, then shown via Javascript), plain href="#" is a leaner and faster alternative to “javascript:” version.

6. style=”…”

There’s nothing inherently wrong with style attribute, except that by moving its contents to an external stylesheet, we can take advantage of resource caching. This is similar to avoiding event attributes, mentioned earlier. Even if you only need to style one particular element and are not planning to reuse its styles, remember that style information has to be transferred every time document is requested. Moving style to external resouce prevents this, as stylesheet is transferred once and then cached on a client.

7.






Needless to say, this kind of “optimization” should never be performed in the public web. Unless the intention is to make documents inacessible to users and search engines. And it hurts me seeing those NOSCRIPT elements, which fall short in clients behind Javascript-blocking firewalls. Bad idea, bad execution.

Antipatterns

Previous snippet was a good example of optimization anti-pattern. There are, however, few more you should be aware of:

1. Removing doctype

HTML Compresor has an option — on by default — to strip doctype. I can’t think of a case where stripping it would be beneficial. On a contrary, missing doctype triggers quirks mode, and as a result, wreaks havoc on a page layout and behavior. Doctypes should be left alone, or instead, replaced with a shorter — HTML 5 — version.

2. Replacing STRONG with B and EM with I

Another harmful option in the same HTML Compressor is to replace elements with their shorter “alternatives”. The problem here is that B is not really an alternative to STRONG. Neither is I a replacement to EM. STRONG and EM elements have semantic meaning — emphasis, whereas B and I are simply font-style elements; They affect text rendering, but carry no semantic meaning.
Even though browsers usually display these elements identically, screen readers and search engines very much understand the difference.

3. Removing title, alt attributes, and LABEL elements.

A good rule of thumb is to never optimize in exchange of accessibility. You might be tempted to remove that optional “alt” attribute on IMG elements, or “title” on anchors, but saving few dozens of bytes is really not worth often-critical accessibility loss.

Tools

It’s more or less trivial to automate most of the tweaks from “additional optimizations” section. There already exist tools that strip comments, whitespaces, and remove quotes around attribute values. But these are still in their infancy and perform a very limited set of optimizations. We can definitely do better.
A couple of months ago, hakunin and I started working on a similar, Ruby-based compressor, but never had a chance to finish it.
So what do we have so far?
  1. Absolute HTML Compressor (desktop, windows)
    Does great job, but only after turning off options like stripping doctype and replacing STRONG with I.
  2. HTML Compact (desktop, windows)
    Makes document inaccessible. Avoid.
  3. HTML Compressor (desktop, windows)
    Only removes whitespace, and even in whitespace-sensitive elements, such as PRE. Not very useful.
  4. Pretty Diff (web-based)
    Doesn’t have option to completely remove whitespaces (only collapses them). Doesn’t perform any optimizations except collapsing whitespace and removing newlines. Doesn’t respect whitespace-sensitive elements. Not very useful.
  5. htmlcompressor (java-based)
    Performs most of the optimizations described here (but doesn’t remove optional tags or shorten boolean attributes). Respects whitespace-sensitive elements. It is more or less best option at the moment.
As you can see, current state of affairs is pretty disappointing. There seem to be no compression tools for Mac/Linux, and those for Windows are hardly useful.

Future considerations

Whereas munging and stripping can (and should) be done during production, markup smells is something that should never happen in the first place. Neither in production, nor in development. Not unless, for whatever reason, they are absolutely necessary.
Unsurprisingly, the best optimization one can do is often a manual one: changing document structure to avoid repeating classes on multiple elements (and instead moving them to parent element), or eliminating chunks that are not immediately needed, and instead loading them dynamically. Replacing miriads of
’s or  ’s used inefficiently for presentational purposes, or that old table-based layout are other good examples of manual cleaning.
As far as all the other little tweaks, I expect more compression tools to appear in the near future, pushing size-reduction boundaries even further.
If you know more ways to optimize HTML, please share. I’d be glad to hear any questions, suggestions or corrections.


Better code means better results
Whether your company needs good search engine placements, fast loading times, or an accessible website, good code is at the root of it all.

The Organization of a Web Page Under the Hood
You don't need to be an expert in web design to understand the concept of how a good code structure can help aid in search engine placements and accessibility. Most web design companies create their websites in visual editors such as Dreamweaver or FrontPage, and these programs simply aren't intuitive enough to arrange a website's code in a manner that is always beneficial.

Search engines read a website from the start of the code all the way down to the end of the code. They don't see the presentational side of a website such as images and colors, and this is why hand coding a website is crucial for search engine optimization: the most important content is placed at the very top of the code, even if that content doesn't appear to be the first on the page when it's viewed in a browser. Visual editors arrange the content in a way that is, well, visual. If you could convert a web page made by a visual editor into a book, its table of contents might look like this: Chapter 2, forward, chapter 1, chapter 3.

Lean and Mean
Hand coding a website ensures that there is absolutely nothing hidden on a website that doesn't need to be there, and if you know a little bit about search engine optimization, you are probably aware that keeping the amount of code to a minimum is important.

How This Ties in With Accessibility
Let's face it, the content you want search engines to deem most important on a web page is the content that your visitors are going to want to read first. Similarly, when visitors arrive at your site using a mobile or less capable browser (like a mobile phone's browser), the first thing they will see is the content they are looking for.