Can I change the z-index stacking order for position: absolute elements?
Here's my code:
body {
padding: 50px;
}
.rel {
height: 20px;
width: 100%;
background-color: #efefef;
position: relative;
margin-bottom: 15px;
}
.abs {
position: absolute;
height: 50px;
width: 300px;
background-color: red;
z-index: 1;
}
.abs2 {
position: absolute;
top: 0px;
height: 180px;
width: 50px;
background-color: green;
border: 1px solid black;
top: -40px;
z-index: 2;
}
.shift {
left: 100px;
}
<div class="rel">
<div class="abs">
<div class="abs2">1</div>
</div>
</div>
<div class="rel"></div>
<div class="rel">
<div class="abs">
<div class="abs2 shift">2</div>
</div>
</div>
<div class="rel"></div>
<div class="rel"></div>
Can the green "abs2" div be stacked above the second red "abs" div? Both positional absolutes (every green "abs2" div must be above every red "abs" div).
I know there is something called a stacking context, but I can't figure out how to get my example to work. It seems impossible if I read Mozilla's explanation
source to share
Since all the elements that have .abs
have the same stacking context, you can give a higher value z-index
to the one that contains the green box.
<div class="rel">
<div class="abs higher"> <!--
^-- Added class -->
<div class="abs2"></div>
</div>
</div>
<div class="rel"></div>
<div class="rel">
<div class="abs"></div>
</div>
.abs { position: absolute; z-index:1; }
.abs.higher {
z-index: 2; /* anything bigger than 1 */
}
.abs2 { position: absolute; z-index:1; }
Update
As per your update:
Is it possible to stack the green
.abs2
div above the second red.abs
div? [...] every green.abs2
div must be above every red.abs
div.
Currently both .abs
and .abs2
set a new stacking contexts. Assuming the current markup is .abs2
nested in .abs
, there are two options:
1) Simplest, if possible, put .abs2
next to (and not inside) .abs
in markup so they can share the same stacking context: Example .
<div class="rel">
<div class="abs"></div>
<div class="abs2">1</div>
</div>
.abs { position: absolute; z-index: 1; }
.abs2 { position: absolute; z-index: 2; }
2) Remove property z-index
from .abs
to insert nested position .abs2
at the top of all elements that have a class .abs
: Example .
However, as you can see, in this approach, some parts of the elements .abs
will lag behind the following containers .rel
. This is because positioned elements that are in the same stacking context will stack based on the DOM hierarchy unless they have explicit values z-index
.
Only in this particular instance 1 - based on the demo provided - we can fix this issue by removing the relative
positioning of the elements .rel
. So now the elements .abs
will be positioned relative to the initial containing block (visually, viewport). This means that the properties top
/ right
/ bottom
/ left
will be calculated relative to the viewport: Example .
1This is not a general solution. You must use this method with care.
source to share