How can you figure out the highest z-index in your document?
Solution 1
You could call findHighestZIndex
for a particular element type such as <div>
like this:
findHighestZIndex('div');
assuming a findHighestZindex
function that is defined like this:
function findHighestZIndex(elem)
{
var elems = document.getElementsByTagName(elem);
var highest = Number.MIN_SAFE_INTEGER || -(Math.pow(2, 53) - 1);
for (var i = 0; i < elems.length; i++)
{
var zindex = Number.parseInt(
document.defaultView.getComputedStyle(elems[i], null).getPropertyValue("z-index"),
10
);
if (zindex > highest)
{
highest = zindex;
}
}
return highest;
}
Solution 2
Stealing some code from abcoder site for the sake of clarity:
var maxZ = Math.max.apply(null,
$.map($('body *'), function(e,n) {
if ($(e).css('position') != 'static')
return parseInt($(e).css('z-index')) || 1;
}));
Solution 3
Using ES6 a cleaner approach
function maxZIndex() {
return Array.from(document.querySelectorAll('body *'))
.map(a => parseFloat(window.getComputedStyle(a).zIndex))
.filter(a => !isNaN(a))
.sort()
.pop();
}
Solution 4
I’d like to add my ECMAScript 6 implementation that I use in one of my UserScripts. I’m using this one to define the z-index
of specific elements so that they always appear the highest.
In JS, you can additionally set certain attributes or class names to elements that you may want to exclude. For instance, consider your script setting a data-highest
attribute on an element that you want to appear as the highest element (e.g. a popup); and consider an element with class name yetHigher
that you don’t control, which should be even higher (e.g. a custom context menu). I can exclude these elements with a chained :not
selector. Note that :not([data-highest], .yetHigher)
is possible, but experimental, and only has limited browser support as of January 2021.
let highestZIndex = 0;
// Then later, potentially repeatedly
highestZIndex = Math.max(
highestZIndex,
...Array.from(document.querySelectorAll("body *:not([data-highest]):not(.yetHigher)"), (elem) => parseFloat(getComputedStyle(elem).zIndex))
.filter((zIndex) => !isNaN(zIndex))
);
The lower five lines can run multiple times and update the variable highestZIndex
repeatedly by finding out the maximum between the current highestZIndex
value and all the other computed z-indexes of all elements. The filter
excludes all the "auto"
values.
Solution 5
I believe what you are observing is Voodoo. Without access to your complete style sheet I can of course not tell reliably; but it strikes me as likely that what really has happened here is that you have forgotten that only positioned elements are affected by z-index
.
Additionally, z-index
es aren't assigned automatically, only in style sheets, which means that with no other z-index
ed elements, z-index:1;
will be on top of everything else.
Charlie Kotter
Updated on February 20, 2022Comments
-
Charlie Kotter about 2 years
In order to set a div containing a transparent text image as the highest z-index in my document, I picked the number 10,000 and it solved my problem.
Previously I had guessed with the number 3 but it had no effect.
So, is there a more scientific way of figuring out what z-index is higher than that of all of your other elements?
I tried looking for this metric in Firebug but couldn't find it.
-
Williham Totland almost 15 yearsExcept, of course, that any element can be positioned and z-indexed, not just divs.
-
Boldewyn almost 15 yearsProblem is, that
element.style.zIndex
doesn't find z-indices set in external stylesheets. Google forgetComputedStyle
to find that ones. -
Matthew Lock over 14 yearsWorkaround here for IE's lack of getComputedStyle erik.eae.net/archives/2007/07/27/18.54.15
-
Pramod Prajapati over 12 yearsI'll expand on your second paragraph to explain that only a
z-index
value of <> 0, and notauto
, actually creates a new stacking context. -
ThatGuy over 12 yearsthis one seems to be the most shortest and efficient method of getting z-index i've seen so far.
-
manafi over 11 yearsWhy would you limit it to one element type?
-
user2064000 almost 11 years@ChristopherJamesCalo, it is a generic solution. If you use '*' as the argument of
findHighestZIndex
, it'll get for all elements. -
190290000 Ruble Man almost 10 yearsCurrently doesn't work properly because highest is saved as string. Instead, set zindex after calling parseInt on the z-index that you've found (note: this means you should check for !isNaN() rather than != 'auto').
-
Sam Eaton about 8 yearsThis only works if all z-index are below 999. It is comparing strings so it thinks 999 > 1000. It also assumes that the highest z-index is above zero. It is possible that the highest is a negative number. devmunchies.com/tutorial/finding-highest-z-index-on-page
-
serdar.sanri over 7 yearsWhy not to use Math.max() ?
-
ProfK over 6 yearsThe only answer I've found that isn't limited to the max for a certain element type. I want my z-index higher that all other z-indexes and this is a gem.
-
Micah Murray about 6 yearsWhile I agree this is a best practice and could help in most situations, it doesn't help if you are building a plugin or script that may run on an unknown page where your script isn't privy to the z-index conventions used. (sorry to comment on your 9-year-old post.)
-
Adam Szmyd about 6 yearsSort needs an comparator to work properly. Consider this:
[2 ,1, 100].sort()
gives in result[1, 100, 2]
which is wrong. Use comparator instead:[2 ,1, 100].sort((a,b) => a-b)
which gives correct[1, 2, 100]
-
oriadam over 5 yearselegant but not usable because, from mdn of
Math.max
: "both spread(...)
andapply
will either fail or return the wrong result if the array has too many elements" -
oriadam over 5 yearsusing
sort
seems like a whole lot of unnecessary cpu and memory consumption -
oriadam over 5 yearsAccording to MDN one cannot use
Math.max
to do this: "both spread(...)
andapply
will either fail or return the wrong result if the array has too many elements [...] The reduce solution does not have this problem" -
oriadam over 5 yearsHaving said that, this will probably cover most real life cases as Chrome supports up to 100k values, Firefox 300k, Edge 400k.
-
oriadam over 5 years^ Having said that,
Math.max
can accept up to 100,000 arguments on Chrome, 300,000 on Firefox, 400,000 on Edge, 150,000 on IE11 (tested on Win10, all browsers latest). -
Robert Koritnik over 4 yearsA
reduce
would only go through the set of indices once soO = n
, whilesort
hasO = n log(n)
. So one can easily replacesort
andpop
withreduce
. -
Arsha over 4 yearsThis answer itself did not work. Add
.sort((a,b) => a-b)
as @AdamSzmyd said make it working. -
justdan23 almost 4 yearsI like using jQuery to ensure compatibility across 22 browsers. I also like @serdar.sanri 's comment to improve it with Math.max().
-
Peter W almost 4 years@190290000RubleMan actually the
zindex > highest
is sufficient to rule out cases where zindex is NaN, becauseNaN > highest
would always returnfalse
. -
AWolf over 3 yearsI'd like to leave my fiddle here. I've also added some tests in the fiddle (not sure if I have covered everything).
-
Tina Hammar about 3 yearsI prefer this way. Slightly modified to cover if "highest" is not NaN. + I wanted to increase by 1 to place my element on top.
isNaN(z) || z < highest ? (isNaN(highest) ? 1 : highest + 1) : z
-
podperson about 3 yearsI was about to incorporate your extra isNaN check, but upon reflection realised highest is initialized to a number and never set to anything that could be isNaN. if isNaN(z), highest doesn't need to be increased it's already highest. So for every bad z value it would unnecessarily increment highest.
-
Tina Hammar about 3 yearsYou need the extra
isNaN(z) || z < highest ? (isNaN(highest) ? 1 : highest) : z
check because if no z-index is set, to any element inbody
,highest
will beNaN
and you will probably want to return at least1
from the function to be able to use it forelement.style.zIndex = findHighestZ()
. -
podperson almost 3 yearsAh yes. "auto". Thanks for following up.
-
podperson almost 3 yearsThe larger bug is the parameters are around the wrong way and the default is overridden :) — so it gets simpler rather than more complex when I flip the comparison because NaN will never be > than an actual value.
-
Daniel Bengtsson almost 3 yearspretty similar to what I thought as well. Only, a few things I would change: Have 2 variables - one to record the highest (if it's a number) if not, add +1 to a variable. for auto, etc. return highest declared + the counter for all the autos you found. Guarenteed to be the highest.
-
chovy over 2 yearsthis doesnj't give me the element though. so how can i get the element with the highest z-index?
-
Andrius R. over 2 yearsI'm assuming the prefix
+
is used here instead ofparseInt
, because it works faster.zIndex
can return 'auto', so that gets turned intoNaN
. -
Marek Lisiecki about 2 yearsfirst of all in
map
i recommend to do:parseInt(getComputedStyle(elem).zIndex, 10) || 0
, second thing[...document.querySelectorAll('body > *')]
- changed selector tobody > *
it reduces elements to check. As you know, nested elements with z-Index depends of it's parents elemens, so it is not necessary to check them all, you only have to check childs of interesting element - herebody
-
podperson about 2 yearsI actually don't trust the specified behavior of z-index as described and so this is less efficient and more paranoid.