Debugging CSS in IE6, hasLayout and Zoom
As I’ve learned to build website layouts purely in CSS, I have come across many hacks or workarounds for debugging browser inconsistencies. One that I never quite understood was the declaration
zoom: 1;
I knew that if I applied zoom: 1 to certain elements, a layout that once looked like the elephant man in Internet Explorer 6 would miraculously turn into prince charming. But what is zoom: 1? And why does it fix my broken layouts? This post is meant to shed some light on these issues without getting into the nitty gritty details.
To understand zoom: 1, we must understand the proprietary property hasLayout, courtesy of Internet Explorer (IE). The hasLayout property is an internal flag in IE that tells the browser whether or not a particular element is a “layout” element. IE makes a distinction between a layout element and a non-layout element in more ways than I can enumerate here. Suffice it to say that layout elements and non-layout elements are treated differently when IE renders the page. I have found that layout elements will interact differently with their floated and positioned neighbors. This usually manifests in strange vertical and horizontal spacing between the elements.
The hasLayout property cannot be altered by the style sheet author. It is internal. It is flagged as true by default for certain elements (like <table>, <body>, and <img>). It can also be triggered by the style sheet author by changing certain properties (like width, height, float, and zoom).
The zoom property is one of Internet Explorer’s proprietary CSS properties that allows the style sheet author to enlarge something.
zoom: 2;
The above zoom declaration does as you would expect, it makes something twice as big. So since the zoom property will trigger hasLayout, we can use it to force IE into giving certain elements “layout” which can help us with spacing issues between elements. In order to add zoom but avoid any detrimental effects, we just use
zoom: 1;
This keeps the element at the same size while still triggering hasLayout behind the scenes.
To use zoom: 1 to my advantage, my general rule of thumb has been to code my layouts by testing primarily in Firefox (or another standards compliant browser like Safari or Chrome). During the process of coding it, I will periodically test it in IE7 to make sure there are no major hiccups. Usually, I can get the layout working in both browsers without too many hacks. Once the layout is finalized in Firefox and IE7, I test in IE6. If the layout is way off in IE6, I immediately apply the declaration:
* { zoom: 1; }
which gives “layout” to all elements. This will often fix the major issues in IE6, and the rest is just pixel tweaking with conditional comments.
For a complete reference of hasLayout (much more complete than I have attempted here), read this article on having layout.