IE6 z-index bug

I ran into an IE6 bug the other day which I’ve encountered a few times
before and managed to workaround without really knowing the true
cause. This time I decided to look into what was actually going on.

The problem is the way IE6 treats the z-index css property.

According to the W3C spec, the order in which page elements are drawn
is determined by their position within their surrounding stacking
context
. The page itself is the outermost stacking context, and by
default page elements are positioned in the order in which they appear
in the document. Their z-index is effectively zero:

html
  |- head           (0) }
  '- body           (0) }
       |- div1      (0) } stacking
       |    |- div2 (0) } context
       |    '- div3 (0) }
       '- div4      (0) }

When the z-index css property is applied to an element, this
does 2 things. Firstly it specifies where that element should be
positioned within its surrounding stacking context. A lower index puts
the element behind the others, and a higher one ensures that the
element will be drawn infront of the others. The z-index property also
creates a new stacking context in which its index is zero. The order
in which this element’s children are drawn will be determined by this
new stacking context:

html
  |- head                          (0) }
  '- body                          (0) }
       |- div1 [z-index: 2]  (0) } (2) }
       |    |- div2          (0) }     }
       |    '- div3          (0) }     }
       '- div4                     (0) }

Thus if our div3 is given a z-index of -1:

html
  |- head                                (0) }
  '- body                                (0) }
       |- div1 [z-index: 2]       (0)  } (2) }
       |    |- div2               (0)  }     }
       |    '- div3 [z-index: -1] (-1) }     }
       '- div4                           (0) }

Then the rendering order would be:

html
head
body
div4
div3
div1
div2

The problem with IE6 is that when an element is given the css property
position: relative, it establishes a new stacking context even
if no z-index property has been set with it.

This is extremely annoying because it means that the children of a
relatively positioned element can never be told to render below its
previous siblings or above its subsequent siblings. You’re kind of
“boxed in” to a range of z depths. The workaround? I guess to avoid
using relative positioning, if possible.

Post a Comment