The z-index
style allows you to control what order boxes are painted in. For example, you can make a child element be painted below its parent element:
#parent {
background: rgba(33, 33, 33, 0.7);
}
#child {
width: 100px;
height: 100px;
background: yellow;
position: relative;
z-index: -1;
}
<div id="parent"><div id="child"></div></div>
However, when the parent element is the <body>
tag, this no longer behaves as expected:
body {
background: rgba(33, 33, 33, 0.7);
}
#child {
width: 100px;
height: 100px;
background: yellow;
position: relative;
z-index: -1;
}
<body>
<div id="child"></div>
</body>
The CSS specification §9.9.1 states (emphasis mine):
The root element forms the root stacking context. Other stacking contexts are generated by any positioned element (including relatively positioned elements) having a computed value of 'z-index' other than 'auto'. Stacking contexts are not necessarily related to containing blocks. In future levels of CSS, other properties may introduce stacking contexts, for example 'opacity' [CSS3COLOR].
Within each stacking context, the following layers are painted in back-to-front order:
- the background and borders of the element forming the stacking context.
- the child stacking contexts with negative stack levels (most negative first).
- the in-flow, non-inline-level, non-positioned descendants.
- the non-positioned floats.
- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
- the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
- the child stacking contexts with positive stack levels (least positive first).
If <body>
were the root element, then this behavior would make sense, since that would mean that the <body>
element is always painted first no matter what.
However, in an HTML document, <html>
is the root element. Given that, why can't we place an element under <body>
with the z-index
style?
(This question was motivated by a similar question on the Russian Stack Overflow site.)
The issue here is that if the html element doesn't have a background specified, the canvas adopts the background of the body element, and that gets painted first. CSS 2.1 says:
See what happens when the html element is given a background:
<body>
tag's default positioning isstatic
. And by definition static positioning means ignore all positioning instructions.In other words because z-index property does not apply to elements that have
position:static
, it does not apply tobody
as it's position defaults tostatic
Here's a good discussion on why z-index does not work on
position:static
Because
body
get's a stacking context. Now with z-index, a element can only go behind or forward relative to itssiblings
but never behind its parent. Becausebody
is aparent
element, setting negative z-index on it's child does not take it behind body.Hard to find official, or even authoritative, documentation on this issue, probably because it's not a common real-life scenario, but the issue has been discussed before by Ian Hickson and Tantek Celik, the editors of the CSS Specification.
Below are some parts of a thread from a W3C mailing list in which spec writers discuss the behavior of
z-index
in relation to thebody
element.The essence of the discussion is this:
The browser is right to ignore
z-index
on non-positioned elements (likebody
), becausez-index
applies only to positioned elementsz-indexing of an element is relative only to sibling elements, and not to parent elements, due to the creation of stacking contexts
There's also an interesting note about the behavior of
z-index
withposition: fixed
on thebody
element, but it doesn't look like it was implemented.Tantek Celik:
response from spec writer:
spec writer:
http://lists.w3.org/Archives/Public/www-style/1999Aug/0131.html
Well, there isn't much documentation about this.
But the
<body>
tag can't have any siblings, so why would ever be a need to change its z-index?Is it even considered a 'positioned' element?
You may play with its child elements z-index as you wish and get desired results in any situation, there is no need to over-complicate html with css styles with no reason at all
The
<body>
tag is defaulted to stay on the bottom of the stack. It simply cannot be set as it will always be the lowest possible value.Source: Adobe Forums