Override CSS Z-Index Stacking Context
We can do it using 3D transformation and we will be able to bring any element to the front even if it's trapped inside a stacking context:
.red,
.green,
.blue {
position: absolute;
width: 100px;
color: white;
line-height: 100px;
text-align: center;
}
body,
div:first-child {
transform-style: preserve-3d; /* this is important for the trick to work */
}
.red {
top: 20px;
left: 20px;
background: red;
/*z-index: 1; we no more need this */
transform:translateZ(1px); /* this will do the trick */
}
.green {
top: 60px;
left: 60px;
background: green;
}
.blue {
top: 100px;
left: 100px;
background: blue;
}
<div><span class="red">Red</span></div>
<div><span class="green">Green</span></div>
<div><span class="blue">Blue</span></div>
How to deal with stacking context problem
Since you've created a new stacking context for .parent
, setting z-index
on its children only changes their stacking order relative to other children of the same block. An element can't be layered behind its own stacking context. To put the child behind its parent, let its z-index
work relative to the document (or some other common ancestor that's further up the DOM).
A stacking context is formed... by any...
Element with a position value absolute or relative and z-index value other than auto.
— stacking context
.box {
position: relative;
/* Generate new stacking context here */
}
.parent {
width: 200px;
height: 100px;
background: #168bf5;
margin: 0 0 0 40px;
/* position: relative; */
/* Do not generate new stacking context here */
}
.child {
position: relative;
width: 100px;
height: 200px;
background: #32d19c;
margin: 0 0 0 -40px;
z-index: -1;
}
<div class="box">
<div class="parent">
parent
<div class="child">child</div>
</div>
</div>
CSS: Z-Index Stacking Context
Your element need to be at least position:relative
to use z-index as this property doesn't work with static position (the default value)
as you can read here :
Note: z-index only works on positioned elements (position:absolute,
position:relative, or position:fixed).
* {
box-sizing: border-box;
}
body, html, .container {
height: 100%;
width: 100%;
}
.container {
position: fixed;
z-index: 300;
}
#div1, #div2, #div3 {
position:relative;
opacity: 0.7;
padding: 10px;
}
#div1 {
border: 1px dashed #996;
background-color: #ffc;
height: 33.333%;
z-index: 1;
}
#div2 {
border: 1px dashed #900;
background-color: #fdd;
height: 33.333%;
z-index: 2;
}
#div3 {
border: 1px dashed #696;
background-color: #cfc;
height: 33.333%;
z-index: 3;
transform: translateY(-40px)
}
<div class='container'>
<div id="div1">DIV#1 </div>
<div id="div2">DIV#2</div>
<div id="div3">DIV#3</div>
</div>
How can i make an element from a bottom stacking context stays in front of another higher stacking context?
The short answer is that you can't. This image from MDN's explanation about stacking context explains it well:
There has been talk about escaping stacking context using position: fixed
but it seems this is not happening just yet (see this fiddle and the question that generated it).
Alternate Solution:
For you, a possible alternative solution would be to nest Parent-1
inside Parent-2
and then use position: absolute
to put Parent-1
wherever you want it.
Trying to overwrite z-index with fixed with z-index absolute
Remove z-index: 0
from your .main
css class, instead of removing position relative. If you just remove position relative or z-index, you are dismissing the stacking context (reference) in this main section, but there are still more use cases for having position: relative
than a z-index
(absolute positioned elements contained inside). You do not want to create a stacking context on your main section in cases where the Header has something like a mega menu/drop down navigation, otherwise those menus will display underneath the main section.
If you need any sort of structure in the main section, create child items of .main
so that the stacking context starts there instead of on the same level as the header.
Why position: relative without z-index creates a new stacking context?
Actually, the accepted answer is incorrect - top
, left
, bottom
and right
have nothing to do with this. If you remove the top
and add a negative margin-bottom
, you'll see it still gets drawn on top.
.c1 {
position: relative;
margin-bottom: -50px;
}
.c2 {
background: green;
width: 200px;
height: 200px;
}
<div class="c1">
Why I'm visible?
</div>
<div class="c2"> </div>
How to lay out with z-index positioned elements in a third level hierarchy
So far we haven't found a way to do this using z-index.
The following method may or may not be suitable for your particular use case/overall context but it does solve the problem for the code given in the question.
This snippet uses 3d transforms rather than z-index to position the elements in relation to the viewer who is looking head on to the screen.
Of course we don't actually want to introduce perceptible perspective so the snippet uses a small shift back (0.1px). This seems enough to get the system to position elements on top of each other in the required order but small fractions were ignored (at least on my Windows10 Edge).
div {
width: 300px;
height: 300px;
text-align: center;
position: absolute;
transform-style: preserve-3d;
}
.a {
background-color: aliceblue;
position: relative;
transform: translate3d(0, 0, 0);
}
.a1 {
background-color: red;
left: 20px;
top: 20px;
transform: translate3d(0, 0, -0.1px);
}
.a11 {
background-color: aqua;
left: 10px;
top: 10px;
transform: translate3d(0, 0, -0.2px);
}
.a2 {
background-color: yellow;
top: 40px;
transform: translate3d(0, 0, -0.4px);
}
<div class="a">
A
<div class="a1">
A1
<div class="a11">A11</div>
</div>
<div class="a2">A2</div>
</div>
Which CSS properties create a stacking context?
One or more of the following scenarios will cause an element to establish its own stacking context1 for its descendants:
The root element always holds a root stacking context. This is why you can start arranging elements without having to position the root element first. Any element that doesn't already participate in a local stacking context (generated by any of the other scenarios below) will participate in the root stacking context instead.
Setting
z-index
to anything other thanauto
on an element that is positioned (i.e. an element withposition
that isn'tstatic
).Note that this behavior is slated to be changed for elements with
position: fixed
such that they will always establish stacking contexts regardless of theirz-index
value. Some browsers have begun to adopt this behavior, however the change has not been reflected in either CSS2.1 or the new CSS Positioned Layout Module yet, so it may not be wise to rely on this behavior for now.This change in behavior is explored in another answer of mine, which in turn links to this article and this set of CSSWG telecon minutes.
Another exception to this is with a flex item and a grid item. Setting
z-index
will always cause it to establish a stacking context even if it isn't positioned.
Setting
opacity
to anything less than1
.Transforming the element:
Setting
transform
to anything other thannone
.Setting
transform-style
topreserve-3d
.Setting
perspective
to anything other thannone
.
Creating a CSS region: setting
flow-from
to anything other thannone
on an element whosecontent
is anything other thannormal
.In paged media, each page-margin box establishes its own stacking context.
In filter effects, setting
filter
to anything other thannone
.In compositing and blending, setting
isolation
toisolate
and settingmix-blend-mode
to a value different fromnormal
In will change, setting
will-change
to a property whose any non-initial value would create a stacking context.In masking, setting
clip-path
/mask
with a value other thannone
.
Note that a block formatting context is not the same as a stacking context; in fact, they are two completely independent (although not mutually exclusive) concepts.
1 This does not include pseudo-stacking contexts, an informal term that simply refers to things that behave like independent stacking contexts with respect to positioning, but actually participate in their parent stacking contexts.
Related Topics
How to Make a CSS Triangle with Smooth Edges
Is It Bad Practice to Use Negative Margins or Padding in CSS
CSS Difference Between Background: and Background-Image:
Negative Top Margin Not Working in Ie 8 or 9
Font-Size:62.5% VS. Font-Size:10Px
How to Make a Box with Arrow in CSS
How Are Scrollbars in New Google Docs UI Styled (Esp. the Arrow Buttons)
How to Remove the Blue Halo Glow from Jquery Mobile Input Elements That Receive Focus
CSS Animation with Delay and Opacity
What's the Difference Between a Block-Level Box and a Principal Block-Level Box
CSS Media Type Print Using Background-Color in Chrome
How to Get IE8 to Accept a CSS :Before Tag
Override CSS Z-Index Stacking Context
Horizontal Centered Menu in CSS
CSS Positioning to Fill Container: Width VS. Left/Right