Search code examples
javascripthtmlcsscss-positionz-index

z-index does not work with nested absolute elements


I am trying to develop a dropdown which contains a ul list that is expandable. An element of the list is visible by default. When the list is expanded, all the elements should be visible and it should be positioned over the dropdown. I attached the snippet and as you can see, the list expands but the li elements are not over the dropdown, even though the ul has an absolute position and a greater z-index.

var dropdown = false;
var list = false;

function toggleList () {
  toggle('.hidden', list);
  list = !list;
}

function toggleDropdown () {
  toggle('.dropdown', dropdown);
  dropdown = !dropdown;
}

function toggle (selector, isAlreadyOpened) {
  if(isAlreadyOpened) $(selector).hide();
  else $(selector).show();
}
.parent {
  position: relative;
  background-color: red;
  width: 50%;
}

.dropdown {
  width: 40%;
  height: 100px;
  background-color: blue;
  display: none;
  position: absolute;
  right: 0;
  z-index: 10;
  overflow: hidden;
}

.list {
  position: absolute;
  z-index: 20;
}

.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="parent">
  <button onclick="toggleDropdown()">Toggle dropdown</button>
  
  <div class="dropdown">
    First Dropdown
    
    <button onclick="toggleList()">Toggle list</button>
    <ul class="list">
      <li>1st element</li>
      <li class="hidden">2nd element</li>
      <li class="hidden">3rd element</li>
      <li class="hidden">4th element</li>
      <li class="hidden">5th element</li>
      <li class="hidden">6th element</li>
    </ul>
  </div>
</div>

Someone knows how to help on this? Thanks!


Solution

  • Remove overflow: hidden from .dropdown and there you go!

    var dropdown = false;
    var list = false;
    
    function toggleList () {
      toggle('.hidden', list);
      list = !list;
    }
    
    function toggleDropdown () {
      toggle('.dropdown', dropdown);
      dropdown = !dropdown;
    }
    
    function toggle (selector, isAlreadyOpened) {
      if(isAlreadyOpened) $(selector).hide();
      else $(selector).show();
    }
    .parent {
      position: relative;
      background-color: red;
      width: 50%;
    }
    
    .dropdown {
      width: 40%;
      height: 100px;
      background-color: blue;
      display: none;
      position: absolute;
      right: 0;
      z-index: 10;
    }
    
    .list {
      position: absolute;
      z-index: 20;
    }
    
    .hidden {
      display: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div class="parent">
      <button onclick="toggleDropdown()">Toggle dropdown</button>
      
      <div class="dropdown">
        First Dropdown
        
        <button onclick="toggleList()">Toggle list</button>
        <ul class="list">
          <li>1st element</li>
          <li class="hidden">2nd element</li>
          <li class="hidden">3rd element</li>
          <li class="hidden">4th element</li>
          <li class="hidden">5th element</li>
          <li class="hidden">6th element</li>
        </ul>
      </div>
    </div>