堆叠上下文示例 3

描述

此示例展示了在多层 HTML 层次结构中混合多个定位元素,并且使用类选择器分配 z-index 值时出现的问题。

此示例有一个三级分层菜单,由几个定位的 div 元素组成。当用户悬停或点击其父元素时,会显示二级和三级 div 元素。通常,这种菜单是客户端或服务器端脚本生成的,因此样式规则使用类选择器而不是 ID 选择器进行分配。

如果三级菜单部分重叠,那么管理堆叠可能会成为一个问题。

一级菜单是相对定位的,创建了一个堆叠上下文。

二级菜单绝对定位在其父元素内部。为了将其置于所有一级菜单之上,使用了 z-index 属性。问题是,对于每个二级菜单,都会创建一个堆叠上下文,并且每个三级菜单都属于其父级的上下文。

因此,三级菜单将堆叠在以下二级菜单之下,因为所有二级菜单共享相同的 z-index 值,并且应用默认的堆叠规则。

为了更好地理解这种情况,下面是堆叠上下文层次结构(三个点“...”表示前一行的多次重复)

  • 根堆叠上下文
    • 级别 #1

      • 级别 #2 (z-index: 1)

        • 级别 #3
        • 级别 #3
      • 级别 #2 (z-index: 1)

      • 级别 #2 (z-index: 1)

    • 级别 #1

    • 级别 #1

可以通过删除不同级别菜单之间的重叠,或者通过使用通过 ID 选择器而不是类选择器分配的单独(和不同)z-index 值,或者通过扁平化 HTML 层次结构来避免此问题。

注意:在源代码中,您将看到二级和三级菜单由包含在绝对定位容器中的多个 div 元素组成。这有助于将它们全部一次性分组和定位。

示例

HTML

html
<div class="lev1">
  LEVEL #1

  <div id="container1">
    <div class="lev2">
      LEVEL #2 <br />z-index: 1;

      <div id="container2">
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
        <div class="lev3">LEVEL #3</div>
      </div>
    </div>

    <div class="lev2">LEVEL #2 <br />z-index: 1;</div>
    <div class="lev2">LEVEL #2 <br />z-index: 1;</div>
    <div class="lev2">LEVEL #2 <br />z-index: 1;</div>
  </div>
</div>

<div class="lev1">LEVEL #1</div>
<div class="lev1">LEVEL #1</div>
<div class="lev1">LEVEL #1</div>

CSS

css
div {
  opacity: 0.9;
}
.lev1 {
  width: 250px;
  height: 70px;
  position: relative;
}

#container1 {
  z-index: 1;
  position: absolute;
  top: 30px;
  left: 75px;
}

.lev2 {
  width: 200px;
  height: 60px;
  position: relative;
}

#container2 {
  z-index: 1;
  position: absolute;
  top: 20px;
  left: 110px;
}

.lev3 {
  z-index: 10;
  width: 100px;
  position: relative;
}

结果

另见