[css] z-index not working with fixed positioning

I have a div with default positioning (i.e. position:static) and a div with a fixed position.

If I set the z-indexes of the elements, it seems impossible to make the fixed element go behind the static element.

_x000D_
_x000D_
    #over {
      width: 600px;
      z-index: 10;
    }
    
    #under {
      position: fixed;
      top: 5px;
      width: 420px;
      left: 20px;
      border: 1px solid;
      height: 10%;
      background: #fff;
      z-index: 1;
    }
_x000D_
    <!DOCTYPE html>
    <html>
       <body>
          <div id="over">
             Hello Hello HelloHelloHelloHelloHello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
          </div>  
          <div id="under">
          </div>
       </body>
    </html>
_x000D_
_x000D_
_x000D_

Or on jsfiddle here: http://jsfiddle.net/mhFxf/

I can work around this by using position:absolute on the static element, but can anyone tell me why this is happening?

(There seems to be a similar question to this one, (Fixed Positioning breaking z-index) but it doesn't have a satisfactory answer, hence I am asking this here with my example code)

This question is related to css z-index

The answer is


I was building a nav menu. I have overflow: hidden in my nav's css which hid everything. I thought it was a z-index problem, but really I was hiding everything outside my nav.


z-index only works within a particular context i.e. relative, fixed or absolute position.

z-index for a relative div has nothing to do with the z-index of an absolutely or fixed div.

EDIT This is an incomplete answer. This answer provides false information. Please review @Dansingerman's comment and example below.


since your over div doesn't have a positioning, the z-index doesn't know where and how to position it (and with respect to what?). Just change your over div's position to relative, so there is no side effects on that div and then the under div will obey to your will.

here is your example on jsfiddle: Fiddle

edit: I see someone already mentioned this answer!


Add position: relative; to #over

_x000D_
_x000D_
    #over {_x000D_
      width: 600px;_x000D_
      z-index: 10;_x000D_
      position: relative;    _x000D_
    }_x000D_
    _x000D_
    #under {_x000D_
      position: fixed;_x000D_
      top: 5px;_x000D_
      width: 420px;_x000D_
      left: 20px;_x000D_
      border: 1px solid;_x000D_
      height: 10%;_x000D_
      background: #fff;_x000D_
      z-index: 1;_x000D_
    }
_x000D_
    <!DOCTYPE html>_x000D_
    <html>_x000D_
    <body>_x000D_
     <div id="over">_x000D_
      Hello Hello HelloHelloHelloHelloHello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello_x000D_
     </div>  _x000D_
    _x000D_
     <div id="under"></div>_x000D_
    </body>_x000D_
    </html>
_x000D_
_x000D_
_x000D_

Fiddle


When elements are positioned outside the normal flow, they can overlap other elements.

according to Overlapping Elements section on http://web.archive.org/web/20130501103219/http://w3schools.com/css/css_positioning.asp


Give the #under a negative z-index, e.g. -1

This happens because the z-index property is ignored in position: static;, which happens to be the default value; so in the CSS code you wrote, z-index is 1 for both elements no matter how high you set it in #over.

By giving #under a negative value, it will be behind any z-index: 1; element, i.e. #over.


the behaviour of fixed elements (and absolute elements) as defined in CSS Spec:

They behave as they are detached from document, and placed in the nearest fixed/absolute positioned parent. (not a word by word quote)

This makes zindex calculation a bit complicated, I solved my problem (the same situation) by dynamically creating a container in body element and moving all such elements (which are class-ed as "my-fixed-ones" inside that body-level element)