CSS: Absolute position in a relative block; and IE’s hasLayout property
January 17, 2008 on 2:19 pm | In CSS |What a long title for a post! And it sums up what I’m writing about this time. I’m going to talk about a semi-commonly known CSS trick, as well as a potential problem with Internet Explorer 6 with it and the fix for that. Most advanced CSS coders/web designers will be familiar with this trick, but the beginner to intermediate readers will certainly benefit from this.
CSS Positioning
If you’re reading this, you probably know what CSS positioning is.
When you define the CSS of a div block with position: relative, any top, left, bottom, right attributes you give it will move the block accordingly, from its original position (where it would be if you didn’t move it). Giving it top: 20px will move it 20px below where it would be.
On the other hand, if you define a div block with position: absolute, you are essentially telling it exactly where it should appear on the screen. Giving it top: 0px and left: 0px will put the block at the very top left corner of the page. It also effectively “floats” the element and put it on top of any page element that are in the way, but don’t confuse this with the float attribute in CSS. Also, you can control which element appears on top with z-index, if you have more than one.
That said, let’s get into what I’m really talking about this time…
Absolute positioning within a relative block
That might sound awfully complicated at first, but the idea is simple. You are putting an absolute-positioned block inside a relative-positioned block, like this:
<div style="position: relative;"> <div style="position: absolute;"> </div> </div>
And the reason you’d be doing this is that, when you define a block as relative, the absolute coordinates inside it are contained. In other words, for that nested absolute block, the coordinates of 0,0 start at the top left corner of the parent relative block, instead of the whole page. Giving the nested block the attributes top: 0px and left: 0px will put it at the top left corner of the containing relative block.
This is very useful for positioning elements at a specific place within a block. It’s logical to use absolute positioning in those cases, but it’s not logical to calculate exactly what pixels they should be in terms of the whole page, because your calculations are likely going to be off in different browsers, operating systems, or even just text size settings. When creating very modularized web applications (as a simple example, Facebook apps), you may often find yourself needing to do that.
Other uses of this would be, for instance, making rounded-corners boxes. In my opinion, the best method to create rounded-corners boxes would be to make the images of only the corners, and position them absolutely at the corners of the containing block (which are, top-0/left-0, top-0/right-0, bottom-0/left-0, and bottom-0/right-0); and then simply giving the containing block position: relative (with no top/left/etc. coordinates needed).
The Internet Explorer 6 problem
Sounds almost too nice to be true? You are right, there’s gotta be some problems with that. And the problem is Internet Explorer 6. For all you web developers who use Firefox anyway, it wouldn’t be much of a problem; except that Internet Explorer still has 76% of the browser market (as of this writing; I know, surprising eh?) and the majority of those are IE6 users.
The problem is that, when you use this CSS trick, IE6 doesn’t always start calculating coordinates from the containing relative block. It only does that sometimes. In other times, it just starts calculating them from the corner of the whole page, as if you didn’t have the relative block at all. If you didn’t know better, you might even think it seems to be arbitrary with no patterns.
Fortunately, there is actually reason for it; and better yet, there is even a fix for it!
The problem lies in a hidden property of the Internet Explorer browser, called “hasLayout”. It is not a property where you could set with your CSS. It’s basically a hidden variable kept track by the browser program about each element on the page. To read all about it, you can read On having layout.
To make things easy and sum it up for you, you can “give” a block “layout” by giving it attributes such as float, width, or height. (there are more, but these are the more common ones) But as web designers you know that sometimes you just cannot give attributes like that to a block without messing up your design. Fortunately again, there is an IE6-only fix which doesn’t involve any of that. I stole the code below from this page.
<!--[if IE]><style>
.ie_layout {
height: 0;
he\ight: auto;
zoom: 1;
}
</style><![endif]–>
With this defined, all you have to do is give your parent relative block a class called “ie_layout” to fix the issue. To give a brief explanation of why this works: The HTML comments starting with [if IE] is basically an IE-proprietary command that means, only run the code below for Internet Explorer. The height:0 and the very strange he\ight: auto; (which I don’t fully understand; but yes, it is supposed to be that way, including the backslash) are basically properties that don’t do anything at all to the element, but give it a “layout” (i.e. turning “hasLayout” to true for that element).
That’s about it for today. Hopefully, you’ve picked up something useful from this article!
Update (1/25/07): I actually just read (after posting this) that the Microsoft developers working on IE8 are getting back to the right path: Supporting W3C standards and banishing hasLayout. This is certainly good news, but browsers typically take very long for users to adopt. Most IE users nowadays are still on IE6 even though IE7 has been out for a while. It might very well be a good 4-5 years before IE8 becomes the major browser.
2 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a comment
You must be logged in to post a comment.
Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds.
Valid XHTML and CSS. ^Top^
Save in del.icio.us
StumbleUpon this
[...] now we have a problem. I have written an entry about absolute positioning within a relative block a while ago about what you can do with positioning, so things like the above code is fairly common [...]
Pingback by agum » CSS: z-index - so what appears on top? — March 5, 2008 #
[...] Source [...]
Pingback by agum " CSS: Absolute position in a relative block; and IE’s hasLayout … | CSS Tutorials - CSSHelper.net — March 20, 2009 #