The Z-Index CSS Property: A Comprehensive Look

Advertisement

Most CSS properties are quite simple to deal with. Often, applying a CSS property to an element in your markup will have instant results — as soon as you refresh the page, the value set for the property takes effect, and you see the result immediately. Other CSS properties, however, are a little more complex and will only work under a given set of circumstances.

The z-index property belongs to the latter group. z-index has undoubtedly caused as much confusion and frustration as any other CSS property. Ironically, however, when z-index is fully understood, it is a very easy property to use, and offers an effective method for overcoming many layout challenges.

In this article, we’ll explain exactly what z-index is, how it has been misunderstood, and we’ll discuss some practical uses for it. We’ll also describe some of the browser differences that can occur, particularly in previous versions of Internet Explorer and Firefox. This comprehensive look at z-index should provide developers with an excellent foundation to be able to use this property confidently and effectively.

What is it?

The z-index property determines the stack level of an HTML element. The “stack level” refers to the element’s position on the Z axis (as opposed to the X axis or Y axis). A higher z-index value means the element will be closer to the top of the stacking order. This stacking order runs perpendicular to the display, or viewport.

3-dimensional representation of the Z axis:

3-D Representation of the Z Axis

In order to clearly demonstrate how z-index works, the image above exaggerates the display of stacked elements in relation to the viewport.

The Natural Stacking Order

In an HTML page, the natural stacking order (i.e. the order of elements on the Z axis) is determined by a number of factors. Below is a list showing the order that items fit into a stacking context, starting with the bottom of the stack. This list assumes none of the items has z-index applied:

  • Background and borders of the element that establish stacking context
  • Elements with negative stacking contexts, in order of appearance
  • Non-positioned, non-floated, block-level elements, in order of appearance
  • Non-positioned, floated elements, in order of appearance
  • Inline elements, in order of appearance
  • Positioned elements, in order of appearance

The z-index property, when applied correctly, can change this natural stacking order.

Of course, the stacking order of elements is not evident unless elements are positioned to overlap one another. Thus, to see the natural stacking order, negative margins can be used as shown below:

Grey Box

Blue Box

Gold Box

The boxes above are given different background and border colors, and the last two are indented and given negative top margins so you can see the natural stacking order. The grey box appears first in the markup, the blue box second, and the gold box third. The applied negative margins clearly demonstrate this fact. These elements do not have z-index values set; their stacking order is the natural, or default, order. The overlaps that occur are due to the negative margins.

Why Does it Cause Confusion?

Although z-index is not a difficult property to understand, due to false assumptions it can cause confusion for beginning developers. This confusion occurs because z-index will only work on an element whose position property has been explicitly set to absolute, fixed, or relative.

To demonstrate that z-index only works on positioned elements, here are the same three boxes with z-index values applied to attempt to reverse their stacking order:

Grey Box

Blue Box

Gold Box

The grey box has a z-index value of “9999”; the blue box has a z-index value of “500”; and the gold box has a z-index value of “1”. Logically, you would assume that the stacking order of these boxes should now be reversed. But that is not the case, because none of these elements has the position property set.

Here are the same boxes with position: relative added to each, and their z-index values maintained:

Grey Box

Blue Box

Gold Box

Now the result is as expected: The stacking order of the elements is reversed; the grey box overlaps the blue box, and the blue box overlaps the gold.

Syntax

The z-index property can affect the stack order of both block-level and inline elements, and is declared by a positive or negative integer value, or a value of auto. A value of auto gives the element the same stack order as its parent.

Here is the CSS code for the third example above, where the z-index property is applied correctly:

#grey_box {
  width: 200px;
  height: 200px;
  border: solid 1px #ccc;
  background: #ddd;
  position: relative;
  z-index: 9999;
}

#blue_box {
  width: 200px;
  height: 200px;
  border: solid 1px #4a7497;
  background: #8daac3;
  position: relative;
  z-index: 500;
}

#gold_box {
  width: 200px;
  height: 200px;
  border: solid 1px #8b6125;
  background: #ba945d;
  position: relative;
  z-index: 1;
}

Again, it cannot be stressed enough, especially for beginning CSS developers, that the z-index property will not work unless it is applied to a positioned element.

JavaScript Usage

If you want to affect the z-index value of an element dynamically via JavaScript, the syntax is similar to how most other CSS properties are accessed, using “camel casing” to replace hyphenated CSS properties, as in the code shown below:

var myElement = document.getElementById("gold_box");
myElement.style.position = "relative";
myElement.style.zIndex = "9999";

In the above code, the CSS syntax “z-index” becomes “zIndex”. Similarly, “background-color” becomes “backgroundColor”, “font-weight” becomes “fontWeight”, and so on.

Also, the position property is changed using the above code to again emphasize that z-index only works on elements that are positioned.

Improper Implementations in IE and Firefox

Under certain circumstances, there are some small inconsistencies in Internet Explorer versions 6 and 7 and Firefox version 2 with regards to the implementation of the z-index property.

<select> elements in IE6

In Internet Explorer 6, the <select> element is a windowed control, and so will always appear at the top of the stacking order regardless of natural stack order, position values, or z-index. This problem is illustrated in the screen capture below:

The <select> element appears first in the natural stack order and is given a z-index value of “1” along with a position value of “relative”. The gold box appears second in the stack order, and is given a z-index value of “9999”. Because of natural stack order and z-index values, the gold box should appear on top, which it does in all currently used browsers except IE6:

Gold Box

Unless you’re viewing this page with IE6, you’ll see the gold box above overlapping the <select> element.

This bug in IE6 has caused problems with drop-down menus that fail to overlap <select> elements. One solution is to use JavaScript to temporarily hide the <select> element, then make it reappear when the overlapping menu disappears. Another solution involves using an <iframe>1.

Positioned Parents in IE6/7

Internet Explorer versions 6 and 7 incorrectly reset the stacking context in relation to the nearest positioned ancestor element. To demonstrate this somewhat complicated bug, we’ll display two of the boxes again, but this time we’ll wrap the first box in a “positioned” element:

Grey Box

Blue Box

The grey box has a z-index value of “9999”; the blue box has a z-index value of “1” and both elements are positioned. Therefore, the correct implementation is to display the grey box on top of the blue box.

If you view this page in IE6 or IE7, you’ll see the blue box overlapping the grey box. This is caused by the positioned element wrapping the grey box. Those browsers incorrectly “reset” the stacking context in relation to the positioned parent, but this should not be the case. The grey box has a much higher z-index value, and should therefore be overlapping the blue box. All other browsers render this correctly.

Negative Values in Firefox 2

In Firefox version 2, a negative z-index value will position an element behind the stacking context instead of in front of the background and borders of the element that established the stacking context. Here is a screen capture displaying this bug in Firefox 2:

Firefox 2 and negative values

Below is the HTML version of the above screen capture, so if you view this page in Firefox 3 or another currently-used browser, you’ll see the proper implementation: The background of the grey box (which is the element that establishes the stacking context) appears below everything else, and the grey box’s inline text appears above the blue box, which agrees with the “natural stacking order” rules outlined earlier.

Grey Box

Blue Box

Gold Box

Showcase of Various Usage

Applying the z-index property to elements on a page can provide a quick solution to various layout challenges, and allows designers to be a little more creative with overlapping objects in their designs. Some of the practical and creative uses for the z-index property are discussed and shown below.

Overlapping Tabbed Navigation

The CTCOnlineCME2 website uses overlapping transparent PNG images with z-index applied to the “focused” tab, demonstrating practical use for this CSS property:

CTCOnlineCME Tabbed Navigation3

CSS Tooltips

The z-index property can be used as part of a CSS-based tooltip, as shown in the example below from trentrichardson.com4:

CSS Tooltip5

Light Box

There are dozens of quality light box scripts available for free use, such as the JQuery plugin FancyBox6. Most, if not all of these scripts utilize the z-index property:

JQuery FancyBox7

Light box scripts use a semi-opaque PNG image to darken the background, while bringing a new element, usually a window-like <div> to the foreground. The PNG overlay and the <div> both utilize z-index to ensure those two elements are above all others on the page.

Drop down menus such as Brainjar’s classic Revenge of the Menu Bar8 use z-index to ensure the menu buttons and their drop-downs are at the top of the stack.

Brainjar's Revenge of the Menu Bar9

A unique combination of JQuery animation and z-index can create a unique effect for use in a slideshow or photo gallery, as shown in the example below from the usejquery.com10 website:

Usejquery.com's Unique Gallery11

Polaroid Photo Gallery by Chris Spooner12 utilizes some CSS3 enhancements combined with z-index to create a cool re-stacking effect on hover.

Pure CSS Polaroid Photo Gallery13

In this Fancy Thumbnail Hover Effect14 Soh Tanaka changes z-index values in a JQuery-based script:

Fancy Thumbnail Hover15

CSS Experiments by Stu Nicholls

Stu Nicholls describes a number of CSS experiments on his website CSSplay16. Here are a few that make creative use of the z-index property:

CSS image map17

CSS Image Map18

CSS game19

CSS Game20

CSS Frames Emulation21

CSS Frames Emulation22

Layered Layout Enhancements

The 24 ways23 website implements z-index to enhance the site’s template, weaving year and date columns that stretch the length and width of the site’s content, for a very interesting effect.

Usejquery.com's Unique Gallery24

Fancy Social Bookmarking Box

The Janko At Warp Speed25 site uses z-index in a “fancy share box”:

Fancy Share Box26

Perfect Full Page Background Image

This technique was described by Chris Coyier27 and used on the ringvemedia.com28 website. It implements z-index on content sections to ensure they appear above the “background” image, which is not a background image, but only mimics one:

Perfect Full Page Background Image29

Conclusion

Stacking contexts in CSS are a complex topic. This article did not attempt to discuss every detail on that topic, but instead has attempted to provide a solid discussion of how a web page’s stacking contexts are affected by z-index, which, when fully understood, becomes a powerful CSS property.

Beginning developers should now have a good understanding of this property and avoid some of the common problems that arise when trying to implement it. Additionally, advanced developers should have a stronger understanding of how proper use of z-index can provide solutions to countless layout issues and open doors to a number of creative possibilities in CSS design.

Further Reading

Footnotes

  1. 1 http://www.macridesweb.com/oltest/IframeShim.html
  2. 2 http://www.ctconlinecme.com
  3. 3 http://www.ctconlinecme.com
  4. 4 http://trentrichardson.com/examples/csstooltips/
  5. 5 http://trentrichardson.com/examples/csstooltips/
  6. 6 http://fancybox.net/
  7. 7 http://fancybox.net/
  8. 8 http://www.brainjar.com/dhtml/menubar/
  9. 9 http://www.brainjar.com/dhtml/menubar/
  10. 10 http://thisblog.usejquery.com/2009/03/18/create-a-unique-gallery-by-using-z-index-and-jquery/
  11. 11 http://thisblog.usejquery.com/2009/03/18/create-a-unique-gallery-by-using-z-index-and-jquery/
  12. 12 http://line25.com/tutorials/how-to-create-a-pure-css-polaroid-photo-gallery
  13. 13 http://line25.com/tutorials/how-to-create-a-pure-css-polaroid-photo-gallery
  14. 14 http://www.sohtanaka.com/web-design/fancy-thumbnail-hover-effect-w-jquery
  15. 15 http://www.sohtanaka.com/web-design/fancy-thumbnail-hover-effect-w-jquery/
  16. 16 http://www.cssplay.co.uk
  17. 17 http://www.cssplay.co.uk/articles/imagemap/index.html
  18. 18 http://www.cssplay.co.uk/articles/imagemap/index.html
  19. 19 http://www.cssplay.co.uk/menu/jump.html
  20. 20 http://www.cssplay.co.uk/menu/jump.html
  21. 21 http://www.cssplay.co.uk/layouts/frame.html
  22. 22 http://www.cssplay.co.uk/layouts/frame.html
  23. 23 http://24ways.org
  24. 24 http://24ways.org
  25. 25 http://www.jankoatwarpspeed.com/post/2009/07/13/Create-fancy-share-box-with-CSS-and-jQuery.aspx
  26. 26 http://www.jankoatwarpspeed.com/post/2009/07/13/Create-fancy-share-box-with-CSS-and-jQuery.aspx
  27. 27 http://css-tricks.com/perfect-full-page-background-image/
  28. 28 http://ringvemedia.com/
  29. 29 http://css-tricks.com/perfect-full-page-background-image/
  30. 30 http://www.w3.org/TR/CSS21/zindex.html
  31. 31 http://reference.sitepoint.com/css/z-index
  32. 32 http://css-tricks.com/video-screencasts/40-how-z-index-works/
  33. 33 http://msdn.microsoft.com/en-us/library/ms531188(VS.85).aspx

↑ Back to top Tweet itShare on Facebook

Louis Lazaris is a freelance web developer and author based in Toronto, Canada. He blogs about front-end code on Impressive Webs and curates Web Tools Weekly, a weekly newsletter for front-end developers.

Advertisement
  1. 1

    I make excessive use of the z-index property to make sure the playing cards on Would You Rather Questions correctly stack upon each other. Without z-index, a would you rather game in HTML/CSS/JavaScript would have been near impossible :)

    0
  2. 52

    That is great, i was tryin so hard to get solution and I found it here:)
    gr8 job

    0
  3. 103

    Good one. But I had some issue that z-index doesn’t work in iframe.Just I tried to overlay the iframe video and some content..no luck..any idea/suggestions????

    0
  4. 154

    “If you view this page in IE6 or IE7, you’ll see the blue box overlapping the grey box. This is caused by the positioned element wrapping the grey box. Those browsers incorrectly “reset” the stacking context in relation to the positioned parent, but this should not be the case. The grey box has a much higher z-index value, and should therefore be overlapping the blue box. All other browsers render this correctly.”

    Is there a fix for this?

    0
  5. 205

    Now I know what it means. amazing what you learn when you take the time to find out.
    thanks

    0
  6. 256

    the z-index is maybe one of the most important attributes in modern web design

    0
  7. 307

    The explicit positioning is the secret ingredient.

    More than 2 years later and folks are still thanking you for this post. It just saved my bacon, too, so… THANK YOU!!!!

    0
  8. 358

    The first example in section “Why Does it Cause Confusion?” is wrong – the elements are positioned in contrast of what the example’s text states “But that is not the case, because none of these elements has the position property set.”.

    0
  9. 409

    >The first example in section “Why Does it Cause Confusion?” is wrong

    I’ve just found this article as well and this confused me too. In IE9, the two examples under this topic look identical.

    0
  10. 460

    Dimitar: It’s because Smashing Magazine’s website design has changed since this post was written. Nowadays it uses a css file ( http://media.smashingmagazine.com/themes/smashingv4/stylesheets/0-up.css ) that has this css:

    div, ul, li, form{position:relative}

    Which kind of messes up examples in this post :D

    0
  11. 511

    Great explanation of z-index. I was looking for a good article that would explain it well and you did a great job. Thanks for sharing.
    Shawn

    0
  12. 562

    I was starting to think z-index wasn’t working properly until I read your article and found out that it only works with those three positions. Thanks!

    0
  13. 613

    Hi!

    Any idea why the z-index would affect the font of my drop down menus in safari and chrome? Totally stuck here!

    0
  14. 664

    This might not be the case but if you’re using CSS transitions you might want to add -webkit-transform: translate3d(0,0,0) to all of the elements under the dropdown menu.

    div.dropdown * {
    -webkit-transform: translate3d(0,0,0);
    }
    Hope this helps.

    0
  15. 715

    Hi… Happy to know this.. Useful info….!

    0
  16. 766

    Very nice tut on Z-Index, I now have a much better understanding on using this important CSS property.

    0
  17. 817

    Thanks for the detailed explanation in z-index.

    0
  18. 868

    nice tutorial. BUt one question ?

    z-index:9999 what does the value 9999 means.???? the value 0,1,500 means ???

    0
  19. 919

    Thank you for the tutorial! It’s great!

    I’m having some problems with Slim-Box on my site that is probably due to wrong usage of z-index. This post will definitely help me there.

    The thing is that the overlay shows up in front of the image instead of behind it, so I am trying different z-index values to fix it, but to no avail… The only position property that makes the image appear at all is “absolute”, so I’m keeping that the way it is. But I can’t figure out why different z-index values don’t solve the issue.

    Here is the script, after I changed the values:

    #lbOverlay {position: fixed; z-index: 500; left: 0; top: 0; width: 100%; height: 100%; background: #000; cursor: pointer;}
    #lbCenter, #lbBottomContainer {position: absolute; z-index: 9999; overflow: hidden; background: #fff;}
    .lbLoading {background: #fff url(‘loading.gif’) no-repeat center !important;}
    #lbImage {position: absolute; left: 0; top: 0; border: 10px solid #fff; background-repeat: no-repeat;}
    #lbPrevLink, #lbNextLink {display: block; position: absolute; top: 0; width: 50%; outline: none;}
    #lbPrevLink {left: 0;}
    #lbPrevLink:hover {background: transparent url(prevlabel.gif) no-repeat 0 15%;}
    #lbNextLink {right: 0;}
    #lbNextLink:hover {background: transparent url(nextlabel.gif) no-repeat 100% 15%;}
    #lbBottom {font-family: Verdana, Arial, Geneva, Helvetica, sans-serif; font-size: 10px; color: #666; line-height: 1.4em; text-align: left; border: 10px solid #fff; border-top-style: none;}
    #lbCloseLink {display: block; float: right; width: 66px; height: 22px; background: transparent url(‘closelabel.gif’) no-repeat center; margin: 5px 0; outline: none;}
    #lbCaption, #lbNumber {margin-right: 71px;}
    #lbCaption {font-weight: bold;}

    Any idea what is wrong there?

    Thanks!

    A.

    0
  20. 970

    “If you view this page in IE6 or IE7, you’ll see the blue box overlapping the grey box. This is caused by the positioned element wrapping the grey box. Those browsers incorrectly “reset” the stacking context in relation to the positioned parent, but this should not be the case. The grey box has a much higher z-index value, and should therefore be overlapping the blue box. All other browsers render this correctly.”

    I would love to know how to solve this problem, too. A lot of my clients refuse to upgrade their computers, and refuse to migrate from Exploder. I wonder if there’s a site yet that’s just dedicate to fixing IE6&7 compatibility issues.

    0
  21. 1021

    Here’s a fix for the IE6&7 problem.

    Say you’ve set your positions and for whatever reason it’s just not working… try this.

    1. Give image that’s supposed to be on top a z-index of something high, like 20 or 1000. Anything.

    2.Now give the image intended to be on the bottom a z-index of any NEGATIVE number, like -1 or -354.

    For whatever reason, this seems to work.

    I haven’t tested it with more than two layers. Hopefully it still holds up!!!

    How about some feedback?

    0
  22. 1072

    @Av
    Create a root element that contains all of the elements you wish to use z-index on. I suggest a div but you could even use body I suppose. The trick is to make this root element position: relative; and all of it’s children position: absolute;

    0
  23. 1123

    Thank you! I found this extremely helpful. I was able to finally get an annoying Z-index problem resolved.

    0
  24. 1174

    yva_com@yahoo.es

    April 16, 2014 3:48 pm

    thx man!!

    0

↑ Back to top