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:
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.)
<body>
tag's default positioning is static
. 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 to body
as it's position defaults to static
Here's a good discussion on why z-index does not work on position:static
Update: So why doesn't it work with body { position:relative } ?
Because body
get's a stacking context. Now with z-index, a element can only go behind or forward relative to its siblings
but never behind its parent. Because body
is a parent
element, setting negative z-index on it's child does not take it behind body.