Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Children of z-index: 'auto' vs z-index: 0, and what is "stacking context" in CSS?

Tags:

html

css

z-index

Previously, I believed that a child element could not be z-indexed over an element that is a sibling of its parent element that has a higher z-index than its parent. For example, divs A and B are siblings. Div A has a z-index of 10, and div B has a z-index of 5. Div B has a child element: Div C, with a z-index of 9999. From my understanding, div C will not be positioned above div A, because div C's parent (div B) has a lower z-index than div A. This holds true, unless div B has a z-index of 'auto'. When div B has a z-index of 'auto', which would be '0', as it is inheriting from body, div C positions over div A, even though div B's z-index is actually LOWER than it was when it wasn't working.

From the CSS2 spec, z-index 'auto' is defined as

The stack level of the generated box in the current stacking context is 0. The box does not establish a new stacking context unless it is the root element.

I'm having trouble understanding "stacking context." It seems to be the only difference between a defined z-index of 0, and a default of 'auto' which is 0 but also has no stacking context. More specifically:

Why are children of elements with no stacking content z-indexed differently than those within a stacking context?

Here is a fiddle that shows the difference between z-index of 0, and a z-index of auto. The green div is a child of the blue div, and the red div is a sibling of the blue div.

http://jsfiddle.net/c7Tvt/

like image 495
MattDiamant Avatar asked Apr 29 '13 18:04

MattDiamant


1 Answers

In your example, you have two scenarios, call them Blue and Blue-2.

In Blue, you have two stacking contexts, the first contains #blue and the second contains #red and #green. #blue is in its own stacking context because z-index: auto, and this context is simply part of the default stack.

In Blue-2, you have defined z-index: 0 for #blue, so it is part of the same stacking context as #red. In Blue-2, #blue is painted first because it has the lowest z-index, 0. However, #green is a child of #blue and gets painted over #blue, the parent and child form a new stacking context (a sub-stacking context if you wish). Finally, #red is painted over the blue-green stack because the red z-index is 2, which is greater than the blue z-index of 0. In this case, the z-index of green affects its stacking level with respect to blue and any other child elements in #blue. In Blue-2, there are three stacking contexts, the default (#1), the one for red and blue (#2), and the other that is blue and green (#3).

Key Point
z-index: auto does not start add a positioned element to a new stacking context whereas z-index: 0 does. Remember, there is at least one stacking context, the default one that is defined for the elements by virtue of their natural HTML/DOM order on the page.

Note: I took the liberty of describing the staking position as if you had two web pages, one with #red, #blue, #green and the second with #red2, #blue2, #green2. In reality, since all the div's are on the same page, all the stacking levels contain all the elements. When there are two red div's in the same stack, #red2 would be painted over #red since elements further down the DOM tree are painted over earlier elements.

Reference
I found the following quite useful to read:
https://developer.mozilla.org/en-US/docs/CSS/Understanding_z-index/Stacking_context_example_2

If you want even more detail, try looking at:
http://www.w3.org/TR/CSS21/zindex.html

like image 73
Marc Audet Avatar answered Sep 27 '22 23:09

Marc Audet