On this page
4 different stacks of cards representing layers as in HTML and CSS

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;.

Keep in mind that z-index only works on positioned elements (position: absolute, position: relative, position: fixed, or position: sticky) and flex items (elements that are direct children of display: flex elements).

Practical code example for finding highest z-index

The following code written in JavaScript determines the highest z-index used on the page. You can limit searching by providing CSS selector argument to select elements you want to verify.

Determine highest z-index using JavaScript
function getHighestZindex(selector) {
  const zIndexes = [];

  for (const element of Array.from(document.querySelectorAll(selector || "body *"))) {
    const zIndex = window.getComputedStyle(element, null).getPropertyValue("z-index");

    if (zIndex !== null && zIndex !== "auto") {
      zIndexes.push(Number(zIndex));
    }
  }

  if (zIndexes.length === 0) {
    return 0;
  }

  return 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

Determine highest z-index using JavaScript, but inside the iframe
const iframeWindow = document.querySelector('#exampleIframe').contentWindow;
const iframeDocument = iframeWindow.document;

function getHighestZindex(selector) {
  const zIndexes = [];

  for (const element of Array.from(iframeDocument.querySelectorAll(selector || "body *"))) {
    const zIndex = iframeWindow.getComputedStyle(element, null).getPropertyValue("z-index");

    if (zIndex !== null && zIndex !== "auto") {
      zIndexes.push(Number(zIndex));
    }
  }

  if (zIndexes.length === 0) {
    return 0;
  }

  return Math.max(...zIndexes);
}

The example of how you might do this for the shadowDOM

Determine highest z-index using JavaScript, but inside the shadowDOM
const shadowRoot = document.querySelector('#exampleShadowDomElement').shadowRoot;

function getHighestZindex(selector) {
  const zIndexes = [];

  for (const element of Array.from(shadowRoot.querySelectorAll(selector || "body *"))) {
    const zIndex = window.getComputedStyle(element, null).getPropertyValue("z-index");

    if (zIndex !== null && zIndex !== "auto") {
      zIndexes.push(Number(zIndex));
    }
  }

  if (zIndexes.length === 0) {
    return 0;
  }

  return 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 excludes script and style HTML elements: document.querySelectorAll('body *:not(script, style)');. Note that symbol * is called an universal CSS selector.
  • The for loop instead of forEach, map, filter. Using the for loop can sometimes be faster because it avoids the overhead of calling a function on each iteration loop. Besides, the for loop can be stopped on certain conditions, while forEach, map, and filter must loop to the last item in the loop.

Related posts

Comments

Leave a Reply

Real-user monitoring for Accessibility, Performance, Security, SEO & Errors (SiteLint)