简体   繁体   中英

Unexplained stacking of CSS float and position:relative

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.)

  1. Floated <div> #1 has no z-index or position; the following <div> #2 also has no z-index or position. RESULT: <div> #1 is stacked on top of <div> #2, and mouse interaction is fine.
  2. Floated <div> #1 has no z-index or position; <div> #2 also has no z-index but has position:relative . RESULT: <div> #2 is stacked on top of <div> #1. No mouse interaction is possible.
  3. Floated <div> #1 has 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.
  4. Floated <div> #1 has 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:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. the child stacking contexts with positive stack levels (least positive first).

First off, there are two things you need to remember:

  1. 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.
  2. From my answer to a very similar question : "Floats do not establish stacking contexts on their own. They will only do so if they are positioned and have a z-index that is not auto (not counting any of the numerous other ways an element may do so )."

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.

That is indeed how positioning works.

  1. With no positioning, elements behave as you expect.

  2. Positioning an element does put it in a new stacking context. So a relative div after a non-positioned one behaves as if it is stacked higher. (ie when you cause them to overlap in any way, the second one obscures the first one.)

  3. If you want z-index to work, the element must be positioned. So in scenario 3, the z-index simply does nothing, making it functionally the same as scenario 2.

  4. Therefore, scenario 4 is the solution you want.

Hope this explains things!

Edit: or not. See comments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM