Export (0) Print
Expand All

"HasLayout" Overview

As of December 2011, this topic has been archived. As a result, it is no longer actively maintained. For more information, see Archived Content. For information, recommendations, and guidance regarding the current version of Internet Explorer, see IE Developer Center.

Markus Mielke
Microsoft Corporation

August 31, 2005

What is "HasLayout" and why is it important?

There are several bugs in Internet Explorer that can be worked around by forcing "a layout" (an IE internal data structure) on an element (like, dimensional bug fixes and Holly hack). Most users are not aware of the implications of having "a layout" applied to an element. This document explains what happens when an element has a layout and what implications that has.

To begin with, there are two sets of elements.

  1. Elements that rely on a parent element to size and arrange their contents
  2. Elements that are responsible for sizing and arranging their own contents

In general, elements in Internet Explorer's Dynamic HTML engine are not responsible for arranging themselves. A div or a p element may have a position within the source-order and flow of the document, but their contents are arranged by their nearest ancestor with a layout (frequently body). These elements rely on the ancestor layout to do all the heavy lifting of determining size and measurement information for them.

Note: The element that is responsible for sizing and positioning an element may be an ancestor, not just the element's immediate parent.) The major benefits of each element not having its own layout are performance and simplicity.

So what does "having a Layout" mean?

  • In short, having a layout means that an element is responsible for sizing and positioning itself and possibly any child elements. (If a child element has its own layout, it sizes itself and its descendents, but the original layout positions the child.)
  • Some elements have a "fixed" size or otherwise have special sizing constraints. They always have layout—for example, buttons, images, inputs, selects, and marquee elements have always a native size even if width and height are not specified.
  • Sometimes elements that do not normally require layout information, like a div or a span, may have properties specified that force a layout to be applied in order to support the property—for example, the element must have a layout in order to get scrollbars.
  • Once a layout is applied the "hasLayout" flag is set. This property returns true if queried.

Why is having a layout important?

  • It constrains the element to a rectangular shape. That means content of the element cannot flow around other boxes anymore, for example, floating elements can't impinge on elements with layout boundaries in IE's engine.
  • Elements that do have layout may establish a new block formatting context (9.4.1 in the CSS 2.1 spec)
  • Since layouts are an additional object with cached information, as well as participating in the sizing and positioning algorithms, having a layout is not cheap—it causes increased memory usage and may cause performance degradation.
  • There are also auto-sizing side effects: an element with layout cannot "shrink to fit" its children, so for example an absolute positioned box around an element with layout does not shrink to fit the layout element's children.
  • A layout rectangle grows to the size of its content (height bug in IE 6)
  • A lot of people have used layout to work around IE 6 bugs, particularly with relative positioned elements. However, relative positioned elements do not need a layout, and the side effects of having a layout may cause problems in this case.

Which elements always have a Layout?

Broadly, any element that owns its extents and needs to maintain specific information and functionality to position and render its contents into those extents.

  • Images
  • Tables, TableRows, TableCells
  • HR
  • Input elements: text, button, file, select
  • Marquee
  • Framesets, Frames
  • Objects, applets, plugins
  • Absolute positioned elements
  • Floated elements
  • Inline-block elements
  • Filters (rotation, dropshadow, etc.)
  • Body (as well as HTML element in strict mode)

Which elements can get a Layout?

  • Block level elements with width or height specified under strict mode
  • Any element with width/height specified under compat mode
  • Elements that have the Zoom property set
  • Elements that are in edit mode
  • Elements that host to a viewlinked behavior
  • Layout-flow is different from parent layout flow (rtl to ltr)

Examples of Layout "Hacks"

This link provides a list of known workarounds that are forcing a layout without visual changes. If you see or use them, be aware of their implications. (Thanks to Ingo Chao and the editors for the list.)

Implications of "HasLayout"

Scenario 1: Floating

Let's take a look at the following markup:

<div style="float:left; border: 2px solid red"> 123</div>
   <span style="border: 2px solid blue">
         The quick brown fox jumped over the lazy dog's back.
         The quick brown fox jumped over the lazy dog's back. 
         The quick brown fox jumped over the lazy dog's back.
         The quick brown fox jumped over the lazy dog's back. 
         The quick brown fox jumped over the lazy dog's back.
   </span>

What do we expect?

Bb250481.HasLayout_1(en-us,VS.85).gif

  • You notice that the text flows nicely around the left floated div, as expected.
  • The border is there to demonstrate the outline of the "box" around the span.

What happens when we apply "layout" to the span enclosing the text?

<style>
     .gainlayout {zoom: 1;}
</style>
.
.
.
<span class="gainlayout" style="border: 2px solid blue">

Bb250481.HasLayout_2(en-us,VS.85).gif

  • The applied layout forces the span to become a rectangular box.
  • The text can no longer flow around the div. This is very important since it will destroy the expected layout behavior of text (imagine you applied the Layout to a p tag).

Scenario 2: Auto-sizing

<div style="position: absolute; background:red">
   <div>
      123
   </div>
</div>

What do we expect?

Bb250481.HasLayout_3(en-us,VS.85).gif

  • The first div is positioned absolutely in relationship to its containing block (in this case the viewport) and taken out of the flow.
  • The red background "shrink-wraps" around "123", since the layout is determined by its parent the absolute positioned div.

What happens if we apply "Layout" to the div enclosing the "123"?

<style>
  .gainlayout {zoom: 1;}
</style>

<div style="position: absolute; background:red">
   <div class="gainlayout">
      123
   </div>
</div>

Bb250481.HasLayout_4(en-us,VS.85).gif

  • The div now has ownership of its Layout and completely ignores any "requirements" of its parent.
  • We completely lost the "shrink wrap" behavior initiated by the parent. This is a side-effect you should be aware of if you apply Layout on an element.

Scenario 3: Position:relative

Now let's take a look at an example, where "hasLayout" is used to work around a bug.

<div style="position: relative; border: 2px solid blue">
   <div style="float:left; border: 2px solid red">
      <img style="position: relative; border: 2px solid green; width:100px; height:100px" 
         src="slider.jpg">
   </div>
</div>

We would expect that IE would provide the following outcome.

  • A collapsed blue line 4px solid (collapsed since its children are removed from the flow)
  • A red floated box that will contain a green bordered image

It should look like this.

Bb250481.HasLayout_5(en-us,VS.85).gif

In IE 6 you get a surprise.

Bb250481.HasLayout_6(en-us,VS.85).gif

What just has happened?

  • The image, since it is positioned relative, relies on its parent layout to figure out where it should be positioned.
  • The parent layout is a left floated div, which "has Layout".
  • IE 6's relative positioned measurement code is very brittle (it's a bug and fixed in IE7) and its parent layout makes a mistake in handing down measurement info to the image.
  • Note You also might have noticed that the blue collapsed line does not continue through the red line as it should. This is the first draw back we will notice of "Has Layout". The floating element forms is own layout box and can not be impinged on by the blue div border. In this case it's an internal IE 6 bug.

Traditionally, we would try to work around this issue by forcing a layout.

<style>
  .gainlayout {zoom: 1;}
</style>

<div class="gainlayout" style="position: relative; border: 2px solid blue">

The outcome looks like this.

Bb250481.HasLayout_7(en-us,VS.85).gif

The good:

  • Your image ends up where it should be. (The top level layout forces the correct measurements on to the float and image.)

The bad:

  • The "Layout" of the div has now unwanted side-effects.
    • The blue border is no longer collapsed as it should be but forms a "layout" box around the float and image.
    • Any text that flowed around the float now will be blocked.
    • The perf hit in this scenario is minor but if you put 50 of these on a page. . .you get the point.

In this scenario, there is not much you could have done (besides maybe removing the unnecessary "position:relative" statements) We are not trying to discourage the use of "hasLayout" to work around IE 6 bugs but just trying to explain the implications as well as other issues that you might cause by forcing it. Ideally, all these issues should be fixed, if not in IE 7, then in future versions.

The Take-away

I've attempted to explain a little of the inner workings and side effects of the Trident "hasLayout" feature. I've listed which elements have a built-in layout and when normal elements may get a layout. Finally, I have discussed the implications of having a layout and gave examples of what happens to an element with layout.

Ideally, the user should not and need not know about this feature, since it is mainly used internally by IE to implement CSS positioning. However, it has been discovered as a "cure" for some IE 6 measurement bugs. This feature does not collide with the CSS specifications, since it is used internally to implement the spec (with admittedly existing bugs). With that in mind, I wanted to cast some light on the implications of having a layout.

Additional information can be found at http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp.

Acknowledgements

I would like to thank the Web Standards Group (WaSP) for providing their support and feedback on this article. Especially, I like to thank Dean Edwards and Chris Wilson for their review. Thanks to Holly Bergevin, Ingo Chao, Bruno Fassino, John Gallant, Georg Sørtun, and Philippe Wittenbergh for the thorough discussion of this article. This article is meant to be an extension of community efforts to explain the "hasLayout" mystery with additional information and clarifications. My thanks to everyone involved.

Markus Mielke is a program manager on the Internet Explorer team.


Show:
© 2014 Microsoft