Search code examples
htmlcss-positionz-indexparentfixed

Why doesn't the browser respect the z-index of an element with a "position: fixed" parent?


So I have this fiddle:

https://jsfiddle.net/ionescho/t0qo6z5u/ . With html :

<div id="overlay">
</div>

<div id="top_menu">
    <span>
        fasdfsfafasdfas
    </span>
</div>

and css:

#overlay{
    position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1100;
  background-color: #000;
  opacity: 0.8;
}
#top_menu{
    position:fixed;
    top:0;
    left:0;
    right:0;
    height:200px;
    background-color:red;
    padding-top:40px;
    padding-left:40px;
}
#top_menu > span{
    font-weight:bold;
    color:white;
    font-size:30px;
    z-index:1101;
    position:relative;
}

As you can see, the white text is still behind the semi-transparent overlay. If I modify the span's parent (#top_menu) from "position:fixed" to "position:relative", I get the z-index behavior I was looking for.

However, I cannot lose that "position:fixed" property. Does anyone know why this happens and how can I make a work-around?

Thanks.


Solution

  • Your desired behavior is currently the standard one, and works on Firefox.

    However, according to this answer,

    this behavior is slated to be changed for elements with position: fixed such that they will always establish stacking contexts regardless of their z-index value. Some browsers have begun to adopt this behavior, however the change has not been reflected in either CSS2.1 or the new CSS Positioned Layout Module yet, so it may not be wise to rely on this behavior for now.

    Then if #top_menu establishes a stacking context, the z-index of #top_menu > span will set its z-position inside that stacking context. However, #top_menu is below #overlay.

    To solve the problem you can set a z-index to #top_menu (and thus generate a stacking context on all browsers) with a value higher than #overlay's one. However, then #top_menu's background will be in front of #overlay.

    #top_menu {
      z-index: 1101;
    }
    

    #overlay {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 1100;
      background-color: #000;
      opacity: 0.8;
    }
    #top_menu {
      position: fixed;
      z-index: 1101;
      top: 0;
      left: 0;
      right: 0;
      height: 200px;
      background-color: red;
      padding-top: 40px;
      padding-left: 40px;
    }
    #top_menu > span {
      font-weight: bold;
      color: white;
      font-size: 30px;
      z-index: 1101;
      position: relative;
    }
    <div id="overlay"></div>
    <div id="top_menu">
      <span>fasdfsfafasdfas</span>
    </div>