Software creative always looking for a challenge

Getting Reliable z-index Cross-Browser

Javascript Code

It is not as easy as you might think to get the correct z-index of an element using a javascript call like $(element).css(‘z-index’). The problem is how browser vendors apply the z-index to an element. But, no worries I have created a jsfiddle page to demonstrate the problem and more details on how it works will follow.

View Demo

You may be asking yourself, when will this even be a problem? Well, imagine you want to create a loader (spinner) and you want to overlay the current element with a div displaying an animation to indicate the content is still loading. You will need to assign the loader div with a higher z-index than the content it is supposed to cover for the loader to appear on top. One way to do that is to assign the loader with a z-index equal to the z-index of the element plus one. The problem is that depending on the markup and styling on the element you may get a different result than you expect.

Browser Results

IE9

IE8

IE7

Chrome

Firefox

Opera

Safari

Element has a z-index Actual # Actual # Actual # auto Actual # Actual # auto
Element’s container has a z-index auto auto 0 auto auto auto auto

The problem is that chrome and safari are reporting a wrong z-index due to a webkit bug which seems to ignore a z-index set on an element that has position set to static. It makes sense, if you think about it, static elements (the default position type) are not affected by the z-index property set on them, since they are never overlaid on top of another element (that is what it means to have a static element). It seems then that webkit ignores the z-index in the getComputedStyles() method
returning the default value: ‘auto’.

To force webkit to consider the z-index on an element all we have to do is change the position type to anything other than static (i.e. relative, absolute or fixed). This will apply the z-index to the element and return the correct result.

Another problem is that if the element has no z-index, but its container does, the z-index returned would be auto in all browsers other than IE7, which returns 0. To deal with this situation we need to specify that the z-index should be inherited from the container. We do this by saying z-index: inherit, which will solve our problems in most browsers. IE7 proves to be different, luckly it is different enough that we can write a simple if statement to check if the value returned is zero, if it is, get the value from the parent.

That is all we need to do to get reliable z-index reading across all browsers. Enjoy :).

References:

W3C Specification – z-index http://www.w3.org/TR/CSS2/visuren.html#z-index
W3C Specification – position http://www.w3.org/TR/CSS2/visuren.html#propdef-position
Webkit Bug https://bugs.webkit.org/show_bug.cgi?id=15562
Microsoft z-index property http://msdn.microsoft.com/en-us/library/ms531188(v=vs.85).aspx

Be Sociable, Share!