A common complaint I hear from developers is “Why isn’t z-index working?” Usually they’re having trouble getting an element to appear over other element.
They know that higher z-index means closer to the viewer’s screen, so they set
But still, the element does not appear above other elements.
This problem is caused because some parent of the element has a z-index set. A child element can never have a higher z-index than it’s parent element.
Z-index is not a global layer system; it exists within the scope of each element. All elements begin on the same global scope, but when a z-index value is defined the scope resets for it’s children.
Example time! In the following example, the blue box has a
z-index: 1;, while the green box has
z-index: 2;. The red box is a child of the blue box.
The red box has
z-index: 999; but appears below the green box, even though the red box has a higher z-index. This is because the red box is a child of the box with a red border that has
Because the parent element (blue box) has a
z-index: 1, the child element will never be rendered higher than
z-index: 2. Every child element will exist between
z-index values of 1 and 2, but never greater. A child element can never have a higher z-index than it’s parent.
However, this is only true in the scope of each parent element individually. When two parents have the same z-index, one is rendered in front of the other.
In the following example, both blue boxes have
z-index: 1;. The red box has
z-index: 999 and is a child of the box on the left.
Even though both elements have the same
z-index the boxes are rendered in reverse order. This means that the first box is actually rendered behind the second box.
Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
Because both the green and blue boxes have the same z-index, the blue box is once again rendered “under” the green box. And again, because the red box is a child of the blue box, it is also rendered under the green box.