IE hasLayout "Property"

Where Did It Come From?

A quote from Fumle.dk:

MSIE has quite dated rendering engine (not surprising, as IE is based on Mosaic). In old tabular times, almost any element (except inline content) was a box. There was no way for content to leak from containing table cell, or for table cell to leak out of table...

Many years have passed, and Microsoft began adapting archaic Trident engine to make use of CSS. However, CSS changes the fundamental assumption that old engine was based on - the one that "anything significant" is a rectangle that contains all its content. CSS allows content to overflow out of container. This may happen when content is floated, or if content is too tall/wide to fit inside constrained box.

Why hasLayout?

MicroSoft's "genius" coders decided to fix their ancient engine in a rather bizzare way. And that is where the hasLayout "property" comes from. Every element has hasLayout set to either true or false. If it is set to true - element is a box that is responsible for rendering itself. Therefore, element would be expanded to contain overflowing content, such as floats or very_very_long_words_without_any_breaks. If hasLayout is set to false - element does not render itself, and instead hopes that some ancestor with hasLayout set will do the job for it. This is where the majority of IE bugs come to life.

The hasLayout "property" is not a CSS property, you can not set it with {hasLayout: true;} it would be too easy. An element with hasLayout set to true is often refered to as having layout, and hasLayout of false is refered to as not having layout.

Alright, Be Honest, Which One of You Has Layout?

The following elements have layout by default.

  •   <html>, <body>
  •   <table>, <tr>, <th>, <td>
  •   <iframe>, <embed>, <object>, <applet>
  •   <img>
  •   <hr>
  •   <input>, <button>, <select>, <textarea>, <fieldset>, <legend>
  •   <marquee>

This list might be incomplete. Many of these elements are not even mentioned in the MicroSoft's documentation. However, it is very easy to test whether or not an element has layout or not. For example, consider the following code:

<div id="menu">
   ...
</div>

To determine hasLayout value for that <div> we could run this code in the location bar (this is where you would usualy type the address of the page):

javascript:alert(document.getElementById('menu').currentStyle.hasLayout)

Alternatively, a short form will also work:

javascript:alert(menu.currentStyle.hasLayout)

After running this code a message box should appear saying true or false which would represent the hasLayout value of the element with an ID set to menu. If you get undefined it could mean that you specified a wrong ID, check your spelling.

Give Me Layout! Please!

Setting hasLayout to true, or in other words giving layout, is relatively easy as opposed to setting it to false.

The following properties/values give an element layout:

  •   position: absolute
  •   float: left or right
  •   display: inline-block
  •   width: any value other than auto
  •   height: any value other than auto
  •   zoom: any value other than normal
  •   writing-mode: tb-rl

As of IE7, overflow also sets hasLayout to true.

  •   overflow: hidden or scroll or auto
  •   overflow-x: hidden or scroll or auto
  •   overflow-y: hidden or scroll or auto

You may be not familiar with zoom and writing-mode properties. Both are MicroSoft's proprietary extentions. They work only in IE and will not validate, therefore, I strongly advise you to put those into condcoms.

Zoom obviously zooms an element. Zoom: 2; will render the element twice its size, zoom: 1; will render the element with normal dimentions, and that is why I personally think this is the best property to use for giving an element layout since it has no other effects on the element.

Writing-mode property is a proposed addition to CSS that determines how the text should be written. The tb-rl value stands for "top to bottom, right to left" a typography style used in East Asia. Western typography is depicted "left to right, top to bottom", which would be lr-tb value for writing-mode property.

Properties overflow-x and overflow-y are not well supported at the moment.

Setting contenteditable attribute also gives an element layout.

<p contenteditable="true">so lame</p>

You should never use this one for setting hasLayout, it is shown here only for informational purpouses. Not only contenteditable is a proprietary MS attribute (thus it works only in IE and will not validate) but also allows the user to edit the content of the element, which in best case will confuse the user.

The hasLayout "property" is read-only, you cannot set it directly with JavaScript for example.

I Don't Want It Anymore!

All sounds good until you come across a bug caused by hasLayout set to true. Since hasLayout is read-only, there is no way to set it to false other than not using properties that set it to true. This of course doesn't apply to elements that have layout by default, you cannot set hasLayout to false on those elements. Luckly, most bugs in IE are caused by element not having layout.

Bugs All Around

With my experience I can say that around eighty percent of IE bugs are caused by an element not having a layout. Peek-a-boo bug, disappearing background bug are perfect examples of that.

Bugs that are caused by the element having layout are not that common to come around. One of them can be seen here:

This is not one line

In IE this text will be shown in one line. It seems that the cause of this bug is that the <b> with hasLayout set to true does not properly inherit the white-space property. Setting white-space: pre on the <b> itself or making sure it doesn't have "layout" fixes the bug.

IE hasLayout bugs are often present themself with the most weird issues. If IE does something that you are having problems to explain with words - the first thing to try would be to give an element hasLayout.

Comments