investigating 'hasLayout'...

...reverse engineering #1...

'hasLayout' vs. 'display: table'…

It is always best to start out with the good browsers, and correct IE/win until it lines up with the others. However, there are times when we actually like what IE/win does, and want the good browsers to replicate it — using W3C-standard CSS.

How about lining up the left edge of a paragraph in the flow with a floating image that's preceding it, no matter the size of the image or the length of the paragraph. Triggering 'hasLayout' will achieve this in IE/win (see: Elements next to floats), so now I just have to replicate it across browser-land.
Oh... it looks like I just made it happen.

If you're in a hurry... this line-up is achieved as in example 4 further down this page.
Might be a good idea to study the available methods in depth though, as "blind copying" have a tendency to fail when injected into 'real world web designs'.

Note that the good browsers don't have to rely on hacks or "bug-riding" in order to achieve such a line-up, and no good browser will apply real 'hasLayout' anyway, since that's a non-standard construction found only in IE/win. W3C has however defined some CSS-properties that solves the same layout-problems when served to a standard-compliant browser.

some old browsers are simply lost…

Standard-compliance is the key to successfull 'reverse engineering' - as in everything CSS-related. We're depending on good browser-support for W3C standard CSS, so don't expect these 'reverse engineering' methods to work flawless in any old version of any browser.

These 'reverse engineering' methods are really 'the way it should be done in the first place'. So as browsers catch up with W3C standards, and users upgrade their browser-versions to the latest and greatest; these methods will come into full play. We will probably still have to hack some non-standard crap into IE/win for quite some time, but we are used to that.

Important: IE Mac does neither understand 'CSS table' nor 'hasLayout'. IE Mac is still around in some numbers on older Mac-OS, and shouldn't be ignored just yet. Thus we should do the right thing, and hide disturbing css from that browser. I've done so in this page - using an @media wrapper.

1: starting off with the basics…

This is how a paragraph in the flow will line up with a floating image. The text is wrapping around the image, while the left edge of the paragraph is ignoring the float's presence. This is normal behavior in all browsers - even in IE/win when 'hasLayout=false'. This is not what we want in this case.

This is a misplaced paragraph that has ended up here by accident. I've made this paragraph long enough to force a few line-breaks, and added some basic styles to it. Apart from that it doesn't make much sense to read it, and I might as well have used 'Lorem ipsum' or something of that nature.

basic style:

p {
border-left: solid 2px #39c
}

Note: the above style is applied to all test-paragraphs.

2: 'hasLayout'…

No good browser will make anything useful out of this.

working in:
  • IE/win only

This is a misplaced paragraph that has ended up here by accident. I've made this paragraph long enough to force a few line-breaks, and added some basic styles to it. Apart from that it doesn't make much sense to read it, and I might as well have used 'Lorem ipsum' or something of that nature.

added style:

p {
height: 100%;
}

Note: This non-standard line-up caused by 'haslayout' is what we want to replicate in standard-compliant browsers.

3: 'margin-left'…

Works well as long as we know the width of the image - including border.

working in:
  • IE/win
  • Opera 8.0
  • Firefox 1.0
  • Safari 1.2.4
  • iCab

This is a misplaced paragraph that has ended up here by accident. I've made this paragraph long enough to force a few line-breaks, and added some basic styles to it. Apart from that it doesn't make much sense to read it, and I might as well have used 'Lorem ipsum' or something of that nature.

added style:

p {
margin-left: 39px;
}
* html p {
margin-left: 41px;
}

Note: no hacks needed, but we will need to apply separate 'margin-left: values' to each element that should line up along side of images with different width.

4: 'hasLayout' & 'display: table'…

Works regardless of image-size.

working in:
  • IE/win
  • Opera 8.0
  • Firefox 1.0
  • Safari 1.2.4
  • iCab

This is a misplaced paragraph that has ended up here by accident. I've made this paragraph long enough to force a few line-breaks, and added some basic styles to it. Apart from that it doesn't make much sense to read it, and I might as well have used 'Lorem ipsum' or something of that nature.

added style:

p {
display: table; 
height: 100%;
}

See: case-related test / example.

...and when reversing side, using the same style on the paragraph...

This is a misplaced paragraph that has ended up here by accident. I've made this paragraph long enough to force a few line-breaks, and added some basic styles to it. Apart from that it doesn't make much sense to read it, and I might as well have used 'Lorem ipsum' or something of that nature.

Note: no need to hack in the 'hasLayout' trigger for IE/win only, as 'height: 0' is interpreted as 'min-height' in a standard-compliant browser when 'display: table' is applied. That standard-compliant interpretation of 'height' is similar to how IE/win interpret 'height', so here we have a cross-browser reliable solution for that too.

Note also that 'margin: (not zero)' on 'display: table' is interpreted differently in browsers, depending on whether they follow the latest revision of css2.1 or earlier drafts. That's not appearant here, as 'margin: 0' is applied and 'padding: 3px' is used for finetuning.

5: 'hasLayout' & 'display: table-cell'…

Works regardless of image-size.

working in:
  • IE/win
  • Opera 8.0
  • Firefox 1.0
  • Safari 1.2.4 (pretty buggy)
  • iCab

This is a misplaced paragraph that has ended up here by accident. I've made this paragraph long enough to force a few line-breaks, and added some basic styles to it. Apart from that it doesn't make much sense to read it, and I might as well have used 'Lorem ipsum' or something of that nature.

added style:

p {
display: table-cell;
}
* html p {
float: left /* or right */;
}
*:first-child+html p {
float: left /* or right */;
}

...and when reversing side, using a similar style on the paragraph...

This is a misplaced paragraph that has ended up here by accident. I've made this paragraph long enough to force a few line-breaks, and added some basic styles to it. Apart from that it doesn't make much sense to read it, and I might as well have used 'Lorem ipsum' or something of that nature.

Note: 'float: left|right' is triggering 'hasLayout' by default in IE/win. Other browsers will choke on this, so once again we have to hack in the 'hasLayout' trigger for IE/win only. We can however use the 'height: 100%' without hacking it in, as 'height' is once again interpreted as 'min-height' in standard-compliant browsers.

The pretty nonsensical *:first-child+html selector is a hack for targeting IE7. The need for such a hack for the most recent IE/win-version is in itself enough of a reason not to use this solution.

conclusion…

The simple example 4: 'display: table' seems to work best for simulating 'hasLayout' in an Elements next to floats-case — at the moment. Just mind those margins, forget pixel-perfection, and test well across browser-land.

It comes as no big surprice that IE's proprietary 'hasLayout' and W3C standard 'display: table' are displayed similar in many ways. After all: a real <table> is triggering 'hasLayout' by default in IE. The resulting 'Layout' ends up more in line with the 'new block formatting context' CSS 2.1 spec - 9.4.1—when tables are used for page-layout.

However, IE's 'Layout/hasLayout' is/may be applied in cases where 'new block formatting context' shouldn't apply according to W3C standards, and IE's implementation is seriously flawed and buggy. This may be one reason why so many designers who are used to abusing <table> for layout run into problems when they try to clean up their act and use proper CSS for layout — and start crying: "where is my 'layout'?"

'display: table' isn't a universal solution for simulating 'hasLayout'. Mostly because 'hasLayout' in itself can make a whole range of bugs pop up in IE if we're not careful, but also because complex layouts using 'CSS table' is rendered less than perfect in many of those browsers which acts on it. Slightly older browser-versions may get it completely wrong.

As always; there's hope in the future, as browsers gets their rendering-engines tuned more and more in line with W3C standards — or the other way around. Either way, basing our solutions on standards will work to our advantage.

sincerely  georg; sign

Hageland 10.jul.2005
last rev: 04.sep.2007

investigating 'hasLayout'...

additions:

'hasLayout':
an internal flag in Internet Explorer for windows.
- 'hasLyout = false': 'Layout' not applied.
- 'hasLyout = true': 'Layout' applied.

IE6 is in quirks mode.
IE7 is in standard mode.

IE/Mac is excluded from these examples, and will render them buggy or not at all.

external resources

examples…
…2005 - 2007