CSS 浮动和 position:relative 无法解释的堆叠

Unexplained stacking of CSS float and position:relative

如果我有一个浮动的 <div id='1' style='float:right;'>controls and links</div> 后跟一个 <div id='2' style='position:relative;'>lorem ipsum text here...</div>

#2 位于
#1 之上,阻止任何鼠标交互。 (如果
#2 具有纯色背景,它会完全隐藏
#1,但仍然 "wraps" 在
#1 周围。)为什么是这样吗?

即使我在两者上都设置了 z-index 值,试图强制浮动

#1 到顶部,这仍然是正确的。

可以考虑四种情况。我已将它们全部放入 this JSFiddle。 (JSFiddle 还使用不透明度来说明堆叠。)

  1. 浮动
    #1 没有 z-index 或位置;以下
    #2 也没有 z-index 或位置。 结果:
    #1 堆叠在
    #2 之上,鼠标交互正常。
  2. 浮动
    #1 没有 z-index 或位置;
    #2 也没有 z-index 但有 position:relative结果:
    #2 堆叠在
    #1 之上。无法进行鼠标交互。
  3. 浮动
    #1 有 z-index:1000 但没有位置;下面的 <div> #2 有 z-index:0position:relative结果:
    #2 仍然堆叠在
    #1 之上。无法进行鼠标交互。
  4. 浮动
    #1 有 z-index:1000position:relative;以下
    #2 有 z-index:0position:relative结果:
    #1 堆叠在
    #2 之上,鼠标交互正常。

我看到过一些类似的 SO 问题,但没有一个能准确解决这个问题。我还阅读了许多 CSS 浮动和定位文章,但 none 似乎解决了这种情况。

这确实是定位的工作原理。

  1. 在没有定位的情况下,元素的行为符合您的预期。

  2. 定位元素会将其置于新的堆叠上下文中。因此,非定位后的相对 div 表现得好像它堆叠得更高。 (即,当您使它们以任何方式重叠时,第二个会遮盖第一个。)

  3. 如果你想让z-index起作用,元素必须被定位。所以在场景 3 中,z-index 什么都不做,使其在功能上与场景 2 相同。

  4. 因此,方案4就是你想要的方案。

希望这能说明问题!

编辑:与否。查看评论。

在处理堆叠顺序时,我建议仔细阅读以下来自 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).

首先,您需要记住两件事:

  1. z-index 对非定位元素没有影响。这包括花车。这就是为什么在你的浮动上设置 z-index,而不定位它,不会改变任何东西。
  2. 来自我对 : "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) 的回答。"

这两点涵盖了为什么在场景 2 和场景 3 中浮动永远不会出现在其定位兄弟的前面:定位兄弟的堆栈级别为 0 (#6),这确保它被绘制在浮动前面 (# 4).

在场景 1 中,未定位的兄弟属于 #3,这就是为什么它被绘制在浮动 (#4) 后面的原因。

在场景 4 中,浮动变得完全无关紧要。您现在在同一个堆栈上下文中有两个定位元素,一个比另一个具有更大的堆栈级别(并且,正如所暗示的 ,大了 完全不必要的 数量),所以堆栈级别较高的那个被涂在堆栈级别较小的那个上。