If I have a floated <div id='1' style='float:right;'>controls and links</div>
followed by a <div id='2' style='position:relative;'>lorem ipsum text here...</div>
, <div> #2 lays on top of the <div> #1, blocking any mouse interaction. (If <div> #2 has a solid background color, it completely hides <div> #1, but still "wraps" around <div> #1.) Why is this so?
This remains true even if I set z-index
values on both, trying to force the floated <div> #1 to the top.
There are four scenarios one can consider. I've put them all into this JSFiddle. (The JSFiddle also uses opacity to illustrate the stacking.)
position:relative
. RESULT: <div> #2 is stacked on top of <div> #1. No mouse interaction is possible.z-index:1000
but no position; the following <div>
#2 has z-index:0
and position:relative
. RESULT: <div> #2 remains stacked on top of <div> #1. No mouse interaction is possible.z-index:1000
and position:relative
; the following <div> #2 has z-index:0
and position:relative
. RESULT: <div> #1 is stacked on top of <div> #2, and mouse interaction is fine.I have seen some similar SO questions, but nothing that exactly addresses this. I've also read a number of CSS float and positioning articles, but none seem to address this scenario.
When dealing with stacking order, I recommend perusing the following list from section 9.9 of CSS2:
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).
First off, there are two things you need to remember:
z-index
has no effect on non-positioned elements. This includes floats. This is why setting z-index
on your float, without positioning it, is not going to change anything.These two points cover why the float never appears in front of its positioned sibling in scenarios 2 and 3: the positioned sibling has stack level 0 (#6), which ensures that it's painted in front of the float (#4).
In scenario 1, the non-positioned sibling falls under #3, which is why it's painted behind the float (#4).
In scenario 4, floating becomes irrelevant altogether. You now have two positioned elements in the same stacking context, one with a greater stack level than the other (and, as implied elsewhere, greater by a completely unnecessary amount), so the one with the greater stack level is painted over the one with the smaller stack level.