MahZeh Tools

Tools > All > April 8th, 2007

Solutions to the IE z-index Bug: CSS

The z-index style rule — seemingly simple at first, suprisingly complicated when you think it through — is an oft-misunderstood part of the CSS2 specification. In on the misunderstanding, evidently, are key members of the Internet Explorer team at Microsoft. Others before me have documented the IE z-index bug (Anne van Kesteren and Kae Verens among them), but I find it easier to grasp with a live example:

A (relative), z-index: 1 2 3 4 none A’ (absolute), z-index: 1 2 3 4 none

B (relative), z-index: 1 2 3 4 none B’ (absolute), z-index: 1 2 3 4 none

This is a common scenario. Blocks A and B are positioned relative, in order that their children A’ (child of block A) and B’ (child of block B) can be positioned absolute relative to the parents’ boundaries. (The CSS2 specification defines a “container block,” against whose boundaries descendants can be positioned, as having a position other than none.) The blocks are positioned such that they overlap each other. By default, they are drawn in document order, putting A on the bottom because it appears (and is drawn) first in the document, and B’ on top because it appears (and is drawn) last.

It only gets sticky when we want the blocks stacked in a different order. Let’s say we want A’ to appear on top of the stack. If we take Mozilla/Firefox’s behavior to represent standards-compliance, then the correct way to accomplish this is to assign a z-index value to A’. Try it.

In Mozilla, A’ jumps to the top like we want. In IE, nothing happens. Actually, something does happen, but it’s not what we expect, and it renders no visible effect. It turns out IE doesn’t treat z-index values as all belonging to the same “stack.” Each of the relative-positioned blocks (A and B) is automatically awarded, by IE, its very own internal z-index stack. In other words, setting z-index on either A’ or B’ only affects its stacking order within its relative-positioned containing block. Because A’ and B’ each has a different relative-positioned container, there is no way in IE to specify their z-index stacking orders relative to each other. Only the relative-positioned parents can be z-index stacked relative to each other. (Although, of course, they couldn’t if they were themselves contained within separate relative-positioned containers.)

To make A’ stack on top of B’, the only pure CSS solution that works in IE is to set z-index for A’s relative-positioned parent, A. And if we want A’ to stack over B’ without A stacking over B, it seems there is no solution that works in IE at all, short of rearranging markup in the document itself.

Solution for Pop-Ups

There is a special case of the z-index problem, involving pop-up items, that can only be solved with JavaScript. I have described the problem and the fix here.

[…] have previous discussed the IE z-index bug and how CSS can, in some situations, be fudged to work around it. Here is a practical scenario in […]

This (complete with the simple demo) is easily one of the better explanations of this z-index vs. DOM-stack behavior that I’ve run across, and was quite helpful in figuring out why a certain structure wasn’t layering the way I’d expected it to. Good stuff!

Tool Groups

Introductions

Encourage Participation How?

MahZeh Creations

?מה זה מה זה

Site contents Copyright Joel Rothschild and MahZeh.org, unless otherwise attributed.

Content management by MahZeh-modified WordPress.