tags:

views:

250

answers:

2

I would like to determine the z-index of an element on an html page from code. I am using jQuery.

jQuery will allow me to check the applied z-index using $(element).css("z-index"). If the z-index is not set on that element directly though, Firefox returns "auto" and IE returns "0". The effective z-index of that node then depends on the z-index of its container.

I figured I could calculate the effective z-index then by looking at the node and its parents until a z-index value is found. The problem is, at least on IE, I cannot disambiguate an element with a z-index of 0 from an element who will inherit the z-index of its parent, as in both cases .css("z-index") returns 0. Any thoughts on how to calculate the actual z-index of an element?

If you want to experiment, you can use this code. On IE it will output "0", "0", "0", "300". On Firefox it will output "auto", "auto", "0", "300".

<html>
<head>
    <script src="http://code.jquery.com/jquery-latest.js"&gt;&lt;/script&gt;

</head>

<body>

<script type="text/javascript">
    alert($("<div></div>").css("z-index"));
    alert($("<div style='position:relative'></div>").css("z-index"));
    alert($("<div style='z-index:0'></div>").css("z-index"));
    alert($("<div style='z-index:100'></div>").css("z-index"));
</script>

</body>
</html>
+1  A: 

on IE, I cannot disambiguate an element with a z-index of 0 from an element who will inherit the z-index of its parent

You're looking for elements that have an effective z-index. z-index is effective only on elements with a position style other than static. So you should look up the parents until you find a positioned element with z-index non-auto.

(This will give you the innermost z-index. Stacking contexts can be nested, so you might instead want to look at the outermost z-index by looking at the furthest ancestor to be positioned.)

On IE6-7, an element without a z-index incorrectly receives an automatic z-index of 0. So this will indeed give you a 0 reading when you look at the positioned element without a z-index in IE6-7... this may be wrong, but it's reflecting IE's already-wrong rendering which you'll have to avoid or work around anyway.

(In IE8 this is finally fixed and you will indeed get auto for the first alert, assuming a suitable doctype/EmulateIE setting to send it into IE8 native mode.)

bobince
Good point that the z-index should only be considered for positioned elements (and any traversal to determine an elements z-index should skip non-positioned elements).
Frank Schwieterman
IE will return a z-index of 0 in cases where the z-index is inherited. IE will however apply the inherited z-index correctly, so the IE6-IE7 scenario is still a problem.
Frank Schwieterman
The bug is that IE6-7 *can't* ‘inherit’ a stacking context on a positioned element. When you get `0` as `z-index` on a positioned element, you can be sure that 0 is the z-index IE is actually using to render the element — even if it shouldn't be according to the CSS spec.
bobince
Hmm that is news to me. Contradicts things I've seen in the past, I will have to experiment to be sure I follow what you're saying. Thanks for the clarification though.
Frank Schwieterman
Google IE z-index bug for endless reports of the issue. Generally, if you're nesting positioned elements it's safest to make sure to put z-index on every positioned elements. Otherwise IE6-7 is likely to render the wrong thing.
bobince
Good point but now you are answering a different question.
Frank Schwieterman
+1  A: 

I see the problem, but I'm not sure it really matters... because zero is the root z-index of the page is 0. In the following code:

alert($("<div id='root' style='z-index:10'><div id='blah'></div><div>").get(0).style.zIndex);
alert($("<div id='root' style='z-index:10'><div id='blah'></div><div>").children('#blah').get(0).style.zIndex);

FF reports 10 and (not 'auto'). IE reports 10 and 0. For IE, if you see a 0, then move up a level. For FF, if you see a blank, then move up a level. And then in either case, if you get to the root, and the value is 'auto' (in FF's condition) then I (guess) you could assume that it is 0. (Maybe that's not a great assumption!)

Michael Bray
"For IE, if you see a 0, then move up a level." This statement assumes that the z-index of the element wasn't set to 0 explicitly. I guess this is unlikely but I ruled this approach out before for this reason. Maybe its possible as the content I'm looking at is ad content, where some of the ad providers might do odd stuff if they can to get more visibility.
Frank Schwieterman
Yeah I get your point.... however I would question... does IE itself distinguish? That is, does it use 0 as a marker to mean "not set"? If that is the case, then setting 0 is no different than not setting it at all. I guess you'll need to run a few actual rendering tests to really know for sure.
Michael Bray