The question couldn't be easier. The z-index values are assigned by style=...
or className
, with Javascript or not. I don't think it matters. How do I find (with Javascript) the highest z-index? (The element it's used in would be nice, but not necessary.)
You can't use the (new) querySelector, because it doesn't query CSS values. Is there someway to query CSS? (Not the stylesheets, but the actual used values.)
Grazi
Get top 5 elements + z-indexes:
Array.from(document.querySelectorAll('*')).map(el => [el, getComputedStyle(el).zIndex]).filter(v => !isNaN(parseInt(v[1]))).sort((a, b) => b[1] - a[1]).slice(0, 5)
The question couldn't be easier. The z-index values are assigned by style=...
or className
, with Javascript or not. I don't think it matters. How do I find (with Javascript) the highest z-index? (The element it's used in would be nice, but not necessary.)
You can't use the (new) querySelector, because it doesn't query CSS values. Is there someway to query CSS? (Not the stylesheets, but the actual used values.)
Grazi
Get top 5 elements + z-indexes:
Array.from(document.querySelectorAll('*')).map(el => [el, getComputedStyle(el).zIndex]).filter(v => !isNaN(parseInt(v[1]))).sort((a, b) => b[1] - a[1]).slice(0, 5)
Share
Improve this question
edited Dec 29, 2020 at 17:30
Rudie
asked Dec 21, 2010 at 21:14
RudieRudie
53.8k42 gold badges135 silver badges175 bronze badges
3
- Duplicate: stackoverflow.com/questions/1118198/… – Evan Mulawski Commented Dec 21, 2010 at 21:20
- I would use PHP Simple HTML DOM for this and you can even edit values of elements, their attributes and so on then save it back to the file or another file etc and return the data in json to your javascript to update whatever element your sHTMLdom returned... You could also return a list of elements that have a z-index "style" attribute set and order them based off of their value resulting in the answer to your question. – Gregory Bowers Commented Dec 29, 2020 at 5:19
- 10 years later LOL – Gregory Bowers Commented Dec 29, 2020 at 5:23
5 Answers
Reset to default 16It's not as simple as finding the element with the highest z-index. Stacking order also depends on tree relationship, so if a static positioned element with the most z-index explicitly set, and if your code retrieved that, it would be useless since z-index is useless on static positioned elements.
In addition, IE's stacking order rules are completely broken so you would have to account for that as well. And you may have to account for iframe/select elements in IE pre 8/9 since they have more stacking order priority than any other nodes.
This would probably be useful: http://www.w3.org/TR/CSS21/zindex.html
You'd have to follow all of those and account for IE bugs in order to have a consistent method of getting the element with the most stacking order priority.
This is a modified version of kennebec's/Pravens code which finds the highest z-index within a stacking context. This version also takes opacity into account.
If all you're looking for is to position an element on top of everything else in the page, simply call highZ(document.body) or just highZ(). It finds the highest z-index of the root stacking context which will do exactly that.
- Only non-statically positioned elements matter within a stacking context.
- Elements that are not positioned do not start a new stacking context. So their descendents may exist in the current stacking context. Hence the recursion.
- Also, if the z-index is 'auto', the element does not start a new stacking context, so you must recurse through its elements.
elements with an opacity value less than 1 start a new stacking context. If an element with opacity less than 1 is not positioned, implementations must paint the layer it creates, within its parent stacking context, at the same stacking order that would be used if it were a positioned element with ‘z-index: 0’ and ‘opacity: 1’. If an element with opacity less than 1 is positioned, the ‘z-index’ property applies as described in [CSS21], except that ‘auto’ is treated as ‘0’ since a new stacking context is always created.
function highZ(parent, limit){ limit = limit || Infinity; parent = parent || document.body; var who, temp, max= 1, opacity, i= 0; var children = parent.childNodes, length = children.length; while(i<length){ who = children[i++]; if (who.nodeType != 1) continue; // element nodes only opacity = deepCss(who,"opacity"); if (deepCss(who,"position") !== "static") { temp = deepCss(who,"z-index"); if (temp == "auto") { // positioned and z-index is auto, a new stacking context for opacity < 0. Further When zindex is auto ,it shall be treated as zindex = 0 within stacking context. (opacity < 1)? temp=0:temp = highZ(who); } else { temp = parseInt(temp, 10) || 0; } } else { // non-positioned element, a new stacking context for opacity < 1 and zindex shall be treated as if 0 (opacity < 1)? temp=0:temp = highZ(who); } if (temp > max && temp <= limit) max = temp; } return max; } function deepCss(who, css) { var sty, val, dv= document.defaultView || window; if (who.nodeType == 1) { sty = css.replace(/\-([a-z])/g, function(a, b){ return b.toUpperCase(); }); val = who.style[sty]; if (!val) { if(who.currentStyle) val= who.currentStyle[sty]; else if (dv.getComputedStyle) { val= dv.getComputedStyle(who,"").getPropertyValue(css); } } } return val || ""; }
You would need to loop through every single element in the DOM and keep track of the max z-index found as you loop, along with the element that has that z-index. Then, when you are done, you will have the element you are looking for.
This is an incredibly intensive piece of script and could kill your users' browsers. Why in the world would you want to do this?
You only need sibling elements to find the highest z-index, so start with a parent element or the body.
And often you have some element with a really high z-index that you want to be always on top- if so, ignore z indexes over a million or whatever is safely above the number of siblings.
You can do it in one function, but the syntax for finding stylesheet values is handy to have around.
function highZ(pa, limit){
limit= limit || Infinity;
pa= pa || document.body;
var who, tem, mx= 1, A= [], i= 0, L;
pa= pa.childNodes, L= pa.length;
while(i<L){
who= pa[i++]
if(who.nodeType== 1){
tem= parseInt(deepCss(who,"z-index")) || 0;
if(tem> mx && tem<=limit) mx= tem;
}
}
return mx;
}
function deepCss(who, css){
var sty, val, dv= document.defaultView || window;
if(who.nodeType== 1){
sty= css.replace(/\-([a-z])/g, function(a, b){
return b.toUpperCase();
});
val= who.style[sty];
if(!val){
if(who.currentStyle) val= who.currentStyle[sty];
else if(dv.getComputedStyle){
val= dv.getComputedStyle(who,"").getPropertyValue(css);
}
}
}
return val || "";
}
alert(highZ())
meder makes a great point! I tried to code it anyway, because I'm bored at work and can't help myself:
NOTE: Will only work on style set using the style attribute (won't capture style set by stylesheets)
function getHighIndex (selector) {
if (!selector) { selector = "*" };
var elements = document.querySelectorAll(selector) ||
oXmlDom.documentElement.selectNodes(selector),
i = 0,
e, s,
max = elements.length,
found = [];
for (; i < max; i += 1) {
e = elements[i].style.zIndex;
s = elements[i].style.position;
if (e && s !== "static") {
found.push(parseInt(e, 10));
}
}
return found.length ? Math.max.apply(null, found) : 0;
}