
How to find the highest z-index on a page using JavaScript
Learn to use JavaScript to find the highest z-index value on a web page. Discover a method for identifying the topmost element with a high z-index.
To find the highest z-index value on a page using JavaScript, you can loop through all the elements on the page and check their z-index values. The element with the highest z-index value will be the one that appears on top of all other elements.
The z-index property in CSS controls the stacking order of overlapping elements on a page. An element with a higher z-index value will appear in front of an element with a lower z-index value. To set an element behind another element, add a negative value like z-index: -1;.
Practical code example for finding highest z-index
The following code written in JavaScript determines the highest z-index used on the page. Optionally, you can specify a CSS selector to limit the search to specific elements. The function also accounts for elements within shadow DOMs.
function getHighestZindex() {
const zIndexes = [];
const allElements = Array.from(document.querySelectorAll('*'));
function collectZIndexes(elements) {
for (const element of elements) {
const zIndex = window.getComputedStyle(element, null).getPropertyValue("z-index");
if (zIndex !== undefined && zIndex !== 'auto') {
zIndexes.push(Number(zIndex));
}
}
}
collectZIndexes(allElements);
const shadowRoots = allElements.filter(el => el.shadowRoot);
for (const root of shadowRoots) {
if (root.shadowRoot === null) {
continue;
}
collectZIndexes(Array.from(root.shadowRoot.querySelectorAll('*')));
}
return zIndexes.length === 0 ? 0 : Math.max(...zIndexes);
}You can also use the document.elementsFromPoint() method to get all elements at a given point on the page and use that instead of Array.from(document.querySelectorAll(selector || "body *")).
Can this method be modified to work with iframes or shadow DOM?
Yes, the method can be modified to work with iframes or shadow DOM. However, due to security reasons, scripts running on a page do not have direct access to the content inside an iframe from a different origin. Similarly, the Shadow DOM provides encapsulation for JavaScript, CSS, and templating, preventing access to the inner DOM structure of shadow trees.
However, if you have control over the iframe or Shadow DOM, you can write a similar function inside the iframe or shadow DOM and call it from the main document.
The example of how you might do this for an iframe
iframeconst iframeWindow = document.querySelector('#exampleIframe').contentWindow;
const iframeDocument = iframeWindow.document;
function getHighestZindexIncludingIframes(selector) {
const zIndexes = [];
const elements = Array.from(iframeDocument.querySelectorAll(selector || "*"));
function collectZIndexes(elements) {
for (const element of elements) {
const zIndex = iframeWindow.getComputedStyle(element, null).getPropertyValue("z-index");
if (zIndex !== null && zIndex !== "auto") {
zIndexes.push(Number(zIndex));
}
}
}
collectZIndexes(elements);
const shadowRoots = elements.filter(el => el.shadowRoot);
for (const root of shadowRoots) {
if (root.shadowRoot === null) {
continue;
}
collectZIndexes(Array.from(root.shadowRoot.querySelectorAll("*")));
}
return zIndexes.length === 0 ? 0 : Math.max(...zIndexes);
}Optimize function for performance
Walking through a large number of DOM elements might significantly slow down the function’s execution. However, a few strategies could be taken into consideration:
- Use
:not()CSS pseudo-class. This helps to exclude certain elements from the list. An example that excludesscriptandstyleHTML elements:document.querySelectorAll('body *:not(script, style)');. Note that symbol*is called an universal CSS selector. - The
forloop instead offorEach,map,filter. Using theforloop can sometimes be faster because it avoids the overhead of calling a function on each iteration loop. Besides, theforloop can be stopped on certain conditions, whileforEach,map, andfiltermust loop to the last item in the loop.
Final words about z-index value
Setting the z-index to a value higher than 2147483647 doesn’t make sense, primarily due to the limitations of how numbers are represented in programming, particularly in CSS. Here’s a breakdown of why this is the case:
- Maximum value: the
z-indexproperty in CSS is limited to a signed 32-bit integer, which means it can represent values from -2147483648 to 2147483647. This range is derived from the binary representation of integers in computing. - Integer overflow: if you attempt to set a z-index value beyond 2147483647, it can lead to integer overflow. This means that the value wraps around to the negative side of the integer range, which can cause unexpected behavior in your layout.
Browser consistency: most modern browsers enforce this limit. For example, tests have shown that browsers like Firefox will not accept a z-index value greater than 2147483647. If you try to set a higher value, it simply won’t be applied.
Firefox 138.0.3 (64-bit), macOS, developer console 
- Practical use: in practice, using extremely high values like 9999 or 99999 is common and sufficient for most design needs. Values beyond this range are rarely necessary and can complicate debugging and maintenance of your CSS.
Comments