I'm trying to tweak the stacking order of some elements; here's an SSCCE.
Given this HTML snippet:
<div id="block1">
<div>Lorem ipsum dolor.</div>
<div id="widget">
<div>Widgety goodness!</div>
</div>
</div>
<div id="block2">
<div>Lorem ipsum dolor.</div>
</div>
<div id="block3">
<div>Lorem ipsum dolor.</div>
</div>
I'm trying to display #widget
on top of #block2
; which with the following CSS, you'll see is problematic without changing the location of #widget
in the node tree.
#block1, #block2, #block3 {
position: relative;
min-height: 50px;
width: 100%;
}
#block1, #block3 {
background-color: #abc;
color: #123;
z-index: 1;
}
#block2 {
background-color: #def;
color: #456;
z-index: 2;
}
#widget {
background-color: #f00;
position: absolute;
z-index: 999;
left: 200px;
top: 40px;
}
As you can see in the fiddle, #widget
is overlapped partially by #block2
; which makes perfect sense as the parent #block1
is lower among siblings in the stacking order.
The obvious answer is: make #widget
a child of #block2
, but unfortunately that's not a solution here. Additionally, the #blockN
elements cannot have their relative z-index
values modified; blocks 1 and 3 must be lower than 2. (by this I mean the calculated values could be different, but #block2
will always be greater than it's siblings). The reason for this, is box-shadow
layering.
Is there any reasonable (read: cross-browser, IE7+) way to remove #widget
from it's stacking context, while retaining it's position, coordinate location, dimensions, etc.?
Using fixed
positioning removes it as desired, however it also obtains all the visual properties of being fixed (which makes it a non-solution)
I reckon this may have been answered in a roundabout way, however I didn't find it. Also, apologies; it appears I may have missed some innocuous but key details in my initial post. I think I've covered them all now.
A stacking context is a group of elements that have a common parent and move up and down the z axis together. In this example, the first parent element has a z-index of 1, so creates a new stacking context. Its child element has a z-index of 999.
When applying certain CSS properties, an element can form a stacking context. Z-index values only have a meaning within the same stacking context. For more information on z-index, I recommend this article. I got a lot of inspiration from it when writing this.
z-index: In order to change the stacking order, we can use z-index. Element with higher z-index is placed on top of the element with lower z-index. Let us use the same. An important thing to note is that in order to use z-index, elements should be positioned. To learn more about CSS, positions, refer this article.
Why is that so? By applying z-index value to an element, a stacking context is formed. The fact that a stacking context is formed means it also affects its child elements (orange box is a child of green box in this case).
Your rules aren't really applying to the elements that you want them to be applied to. You need to explicitly set the z-index on the elements you want to position, in your case that element is the div child of block2. By simply modifying the first selector from:
#block1, #block2 , #block3 {
to
#block1, #block2 div, #block3 {
Your stacking order is corrected. Your z-index rules were being applied to the parents while the children continued to use the default of auto. In your case, by setting the position on #block2 div, you allow your widget to sit on top of the block2 child div.
jsFiddle example
I guess you do not need to change the location of the #widget
. In my view, the answer lies in your question itself. Check this out
Edited CSS:
#block1{
background-color: #abc;
color: #123;
z-index:3;
}
#block3 {
background-color: #abc;
color: #123;
z-index:1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With