Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

z-index not working with fixed positioning

Tags:

css

z-index

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.

    #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;     }
    <!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>

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)

like image 701
DanSingerman Avatar asked Mar 07 '11 11:03

DanSingerman


People also ask

Does Z Index work on position fixed?

Note: z-index only works on positioned elements (position: absolute, position: relative, position: fixed, or position: sticky) and flex items (elements that are direct children of display:flex elements).

Why does my Z Index not work?

You set z-index on a static element By default, every element has a position of static. z-index only works on positioned elements (relative, absolute, fixed, sticky) so if you set a z-index on an element with a static position, it won't work.

Does Z Index require position?

Note: Z index only works on positioned elements ( position:absolute , position:relative , or position:fixed ).

How do you find the Z index without absolute positioning?

Yes: use position:relative; z-index:10 . z-index has no effect for position:static (the default).


2 Answers

This question can be solved in a number of ways, but really, knowing the stacking rules allows you to find the best answer that works for you.

Solutions

The <html> element is your only stacking context, so just follow the stacking rules inside a stacking context and you will see that elements are stacked in this order

  1. The stacking context’s root element (the <html> element in this case)
  2. Positioned elements (and their children) with negative z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
  3. Non-positioned elements (ordered by appearance in the HTML)
  4. Positioned elements (and their children) with a z-index value of auto (ordered by appearance in the HTML)
  5. Positioned elements (and their children) with positive z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)

So you can

  1. set a z-index of -1, for #under positioned -ve z-index appear behind non-positioned #over element
  2. set the position of #over to relative so that rule 5 applies to it

The Real Problem

Developers should know the following before trying to change the stacking order of elements.

  1. When a stacking context is formed
    • By default, the <html> element is the root element and is the first stacking context
  2. Stacking order within a stacking context

The Stacking order and stacking context rules below are from this link

When a stacking context is formed

  • When an element is the root element of a document (the <html> element)
  • When an element has a position value other than static and a z-index value other than auto
  • When an element has an opacity value less than 1
  • Several newer CSS properties also create stacking contexts. These include: transforms, filters, css-regions, paged media, and possibly others. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
  • As a general rule, it seems that if a CSS property requires rendering in an offscreen context, it must create a new stacking context.

Stacking Order within a Stacking Context

The order of elements:

  1. The stacking context’s root element (the <html> element is the only stacking context by default, but any element can be a root element for a stacking context, see rules above)
    • You cannot put a child element behind a root stacking context element
  2. Positioned elements (and their children) with negative z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
  3. Non-positioned elements (ordered by appearance in the HTML)
  4. Positioned elements (and their children) with a z-index value of auto (ordered by appearance in the HTML)
  5. Positioned elements (and their children) with positive z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
like image 29
Mr_Moneybags Avatar answered Sep 29 '22 21:09

Mr_Moneybags


Add position: relative; to #over

    #over {       width: 600px;       z-index: 10;       position: relative;         }          #under {       position: fixed;       top: 5px;       width: 420px;       left: 20px;       border: 1px solid;       height: 10%;       background: #f0f;       z-index: 1;     }
    <!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>

Fiddle

like image 106
stephenmurdoch Avatar answered Sep 29 '22 21:09

stephenmurdoch