CSS: z-index - so what appears on top?
March 5, 2008 on 12:26 am | In CSS |CSS provides an interesting property called z-index, that determines what element appears “on top”, on a page. You can tell that this was put in the CSS standards because of absolute positioning. Imagine the 2D page having X and Y coordinates, and the Z-axis points out of the screen at you, as well as inside to the page.
Interestingly, when these CSS standards were first developed, no one imagined they could become so useful — it’s an important part of what makes web 2.0 applications like meebo possible. (chat windows overlapping others to simulate a desktop application design)
So, when developing web applications nowadays, you could very well have needs to utilize this property. Unfortunately, support for z-index is flaky in browsers. Not every browser interprets code the same way. Unfortunately for developers, Firefox and Internet Explorer, again, have different opinions on z-index.
In this article, I will discuss some potential discrepancies with z-index, and how you can get around them.
Normal Cases
When you are dealing with strictly just absolute-positioned blocks, not nested by anything, you can rely on z-index to be working properly in all browsers. Pretty simple, the higher the z-index number is always on top.
<div style="position: absolute; top: 10px; left: 10px; z-index: 10;">
Box 1
</div>
<div style="position: absolute; top: 20px; left: 20px; z-index: 5;">
Box 2
</div>
Box 1 will appear on top of Box 2 in this example, even though Box 2 came last. Simple enough.
More complicated cases: nesting blocks
Oftentimes, when you are developing web applications, HTML code isn’t so simple. Your view files/the presentation layer could be divided into several files. Plus, to code up a nice user interface, your HTML often gets a little bit complicated and you have a lot of nested div blocks. It’s not uncommon to come across a situation such as this:
<div style="position: relative;">
<div style="position: absolute; top: 10px; left: 10px; z-index: 10;">
Box 1
</div>
</div>
<div style="position: absolute; top: 20px; left: 20px; z-index: 5;">
Box 2
</div>
And 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 are fairly common for advanced CSS coders. Suppose the two blocks above are meant to overlap, with Box 1 appearing on top (you intend so, at least).
Here comes the problem. Firefox still interprets the z-index values and place Box 1 on top. However, Internet Explorer (both IE6 and IE7) does this differently. In IE, Box 2 now appears on top simply because it comes last in the code — because Box 1 belongs in a different stacking context (it’s nested within the parent relative block). The key here is that the parent relative block has no z-index, and by definition it should not create a different stacking context. (it is a different story if the parent relative block defined a z-index value and is, say, 2)
To better illustrate my point in action, here’s a link: IE z-index bug in action.
Try viewing that page in Firefox, and then in IE. It doesn’t matter if you’re on IE6 or IE7.
Detailed readings and work-arounds
It may not be easy to understand what I’m talking about at all in solid terms. The bottom line is, the two major browsers, IE and Firefox, work differently; as witnessed in the above link. The W3C CSS spec for z-index is here for you to read if you are interested.
For a really detailed experiment done on z-index and positioning, here’s a good link: Effect of z-index value to positioned elements. It’s a long read and the examples can be complicated, but it’s worth studying for a good CSS developer.
What I find to be the best work-around is this. For a web application developer, oftentimes we need to create popout div as dialogue boxes (that open when a user clicks something). How do you make sure those boxes’ z-index values work correctly, without anything else (any other elements on the page) appearing on top of it? The simplest way is to make sure all your boxes appear at the end of the page in your HTML, outside of all other blocks.
In my recent work, I actually had complicated enough scenarios where I had to use JavaScript to move my dialogue boxes blocks to the end of the page on page load. I’ll leave it as an exercise for you to think about how to do that; but here’s a tip — appendChild. (Pay attention to “If the node already exists it is removed from current parent node, then added to new parent node.”) ![]()
1 Comment »
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
Thanks a lot for this article - it has helped me work out a bug in IE6… setting the overlapping element to absolute positioning (without setting top/left value) has fixed the issue with z-index height.
Comment by sydneyshan — October 26, 2008 #