9

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>
gregid
  • 111
  • 2
  • 7

2 Answers2

3

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>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thanks, this solved the problem in my application. So the way I understand it works is that the `sticky-header:hover` increases that particular header's `z-index` and the `dropdown` and `dropdown-content` inherirts the increased z-index. – gregid Jul 01 '20 at 11:34
  • @gregid it's not really inheritance but the drowpdown is place inside the stacking context created by the sticky element and I have increased the z-index of the stacking context making all the element inside on the top. related for more details: https://stackoverflow.com/a/54903621/8620333 – Temani Afif Jul 01 '20 at 11:35
  • thank you for the link to the stacking context - great explanation there! – gregid Jul 01 '20 at 11:45
1

You need to give the z-index to the applet divs. Give to the first applet a z-index: 9999 and you will see that the dropdown will be over the others menu

Alberto Sinigaglia
  • 12,097
  • 2
  • 20
  • 48
  • if I understand you correctly you recommend applying individual `z-index` to each applet as in `
    ` and then consecutively go down with index: 9998, 9997, etc. This could work but since my applets are added dynamically it is a bit problematic. Is there any other, generic way to achieve this?
    – gregid Jun 30 '20 at 22:38
  • i can't find a way, if there is. BTW, if you add them dynamically, then you probably can dynamically add the z-index (using the style attribute) @gregid – Alberto Sinigaglia Jun 30 '20 at 22:43
  • Yes, there just few problems with reordering, moving, etc. So not ideal but at least it works! If there will be no generic solution soon I will accept this answer. Thank you. – gregid Jun 30 '20 at 22:48
  • @gregid sure, i'll try to find other solution (possibly more generic ) – Alberto Sinigaglia Jun 30 '20 at 22:51