Search code examples
htmlcssz-indexsticky

Display element over one with position: sticky


I need to display a dropdown content over an element that has position: sticky set. Unfortunately manipulation with z-index didn't help much. The content shown on hover is still covered by next sticky element.

Full example presenting the problem with multiple applets: https://jsfiddle.net/tfkh2v0n/3/

Minimal example:

.applet-container {
  position: relative;
  z-index: 1;
}

.applet {
  position: relative;
  z-index: 2;
}

.sticky-header {
    top: 0px;
    position: sticky;
    background: #d1d1d1;
    z-index: 3;
}

.dropbtn {
  background-color: #4CAF50;
  color: white;
}

.dropdown {
  position: relative;
  display: inline-block;
  z-index: 4;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: gold;
  min-width: 160px;
  z-index: 5;
}

.dropdown-content a {
  display: block;
}

.dropdown:hover .dropdown-content {
  display: block;
  z-index: 5;
}
<div class="applet-container">
  <div class="applet">
      <div class="sticky-header">
        Sticky Header 
        <div class="dropdown">
          <button class="dropbtn">Dropdown</button>
          <div class="dropdown-content">
            <a href="#">Link 1</a>
            <a href="#">Link 2</a>
            <a href="#">Link 3</a>
          </div>
        </div>
      </div>
      <div class="content">Content 1 that will be displayed over</div>
  </div>
    <div class="applet">
      <div class="sticky-header">Dropdown content should be displayed over this sticky header</div>
  </div>
</div>


Solution

  • Get rid of all the z-index (you don't need any of them) and simply set z-index to the sticky element on hover.

    .applet-container {
      position: relative;
      /*z-index: 1;*/
    }
    
    .applet {
      position: relative;
      /*z-index: 2;*/
    }
    
    .sticky-header {
      top: 0px;
      position: sticky;
      background: #d1d1d1;
      /*z-index: 3;*/
    }
    
    .dropbtn {
      background-color: #4CAF50;
      color: white;
    }
    
    .dropdown {
      position: relative;
      display: inline-block;
      /*z-index: 4;*/
    }
    
    .dropdown-content {
      display: none;
      position: absolute;
      background-color: gold;
      min-width: 160px;
      /*z-index: 5;*/
    }
    
    .dropdown-content a {
      display: block;
    }
    
    .dropdown:hover .dropdown-content {
      display: block;
      /*z-index: 5;*/
    }
    
    .sticky-header:hover {
      z-index: 1;
    }
    <div class="applet-container">
      <div class="applet">
        <div class="sticky-header">
          Sticky Header
          <div class="dropdown">
            <button class="dropbtn">Dropdown</button>
            <div class="dropdown-content">
              <a href="#">Link 1</a>
              <a href="#">Link 2</a>
              <a href="#">Link 3</a>
            </div>
          </div>
        </div>
        <div class="content">Content 1 that will be displayed over</div>
      </div>
      <div class="applet">
        <div class="sticky-header">Dropdown content should be displayed over this sticky header</div>
      </div>
    </div>