Search code examples
htmlcsstwitter-bootstrapz-index

Why isn't z-index working on positioned elements?


I want my Bootstrap dropdown menu to appear underneath the navbar, but it doesn't seem to be respecting the z-index style.

Broadly speaking, I have a layout like this:

<nav>         <!-- z-index: 2; -->
  <ul>
    <li>
      <ul>    <!-- z-index: 1; -->
        ...

Both the <nav> and the <ul> have position styles. Here's the full code:

.nav-submenu {
  top: 20px;
  position: absolute;
  z-index: 1;
}
.navitem-left {
  position: relative;
}
nav {
  height: 72px;
  box-shadow: 0 2px 7px 0 rgba(0, 0, 0, 0.10);
  padding-top: 30px;
  position: fixed;
  z-index: 2;
  width: 100%;
}
nav ul {
  list-style-type: none;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<nav>
  <ul>
    <li class="navitem-left">
      <a href="#" class="dropdown-toggle" id="menu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">CLICK ME!</a>
      <ul class="dropdown-menu nav-submenu" aria-labelledby="menu1">
        <li>
          <a href="#">Why aren't I behind the nav?</a>
        </li>
      </ul>
    </li>
  </ul>
</nav>

Why isn't the stacking working for me?


Solution

  • You misunderstood z-index. It specifies the index of that element with respect to the stacking context it belongs to.

    Precisely, since you use z-index: 2 on the nav, the ul belongs to the stacking context established by the nav!

    Remove that z-index to stop the nav from establishing a stacking context, set a negative z-index to the ul, and use non-transparent backgrounds.

    Oh, and last year the CSS WD decided that elements with fixed positioning would always establish a stacking context, so use another positioning.

    @import 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css';
    .nav-submenu {
      top: 20px;
      position: absolute;
      z-index: -10;
    }
    .navitem-left {
      position: relative;
      float: left;
    }
    nav {
      height: 72px;
      box-shadow: 0 2px 7px 0 rgba(0, 0, 0, 0.10);
      padding-top: 30px;
      position: absolute;
      width: 100%;
      background: #fff;
    }
    nav ul {
      list-style-type: none;
      margin: 0;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <nav>
      <ul>
        <li class="navitem-left">
          <a href="#" class="dropdown-toggle" id="menu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">CLICK ME!</a>
          <ul class="dropdown-menu nav-submenu" aria-labelledby="menu1">
            <li>
              <a href="#">Why aren't I behind the nav?</a>
            </li>
          </ul>
        </li>
      </ul>
    </nav>