Skip to content

Instantly share code, notes, and snippets.

@jeferson-sb
Last active January 26, 2026 16:04
Show Gist options
  • Select an option

  • Save jeferson-sb/4bebc6f421e6c50090118f7006a2a854 to your computer and use it in GitHub Desktop.

Select an option

Save jeferson-sb/4bebc6f421e6c50090118f7006a2a854 to your computer and use it in GitHub Desktop.
Find stacking context on the page
/**
* Will return all elements that create a stacking context in the parent tree.
* @param {HTMLElement} root - The root element to start the search from.
* @example const stackingContexts = listStackingContexts(document.body)
*/
function listStackingContexts(root) {
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT)
const stackingContexts = new Map()
const contextStack = []
if (root instanceof HTMLElement && isStackingContext(root)) {
const rootChildren = new Map()
stackingContexts.set(root, rootChildren)
contextStack.push({ node: root, children: rootChildren })
}
let currentNode = null
while ((currentNode = walker.nextNode())) {
while (
contextStack.length > 0 &&
!contextStack[contextStack.length - 1].node.contains(currentNode)
) {
contextStack.pop()
}
if (!isStackingContext(currentNode)) continue
const childrenMap = new Map()
if (contextStack.length > 0) {
contextStack[contextStack.length - 1].children.set(currentNode, childrenMap)
} else {
stackingContexts.set(currentNode, childrenMap)
}
contextStack.push({ node: currentNode, children: childrenMap })
}
return stackingContexts
}
function isStackingContext(elementNode) {
const styles = elementNode.computedStyleMap()
const zIndex = styles.get('z-index').value
const opacity = styles.get('opacity').value
const position = styles.get('position').value
const blendMode = styles.get('mix-blend-mode').value
const isolation = styles.get('isolation').value
const containerType = styles.get('container-type').value
const willChange = styles.get('will-change').value
const scenarios = {
zIndex: zIndex !== 'auto',
opacity: opacity < 1 && position !== 'static',
blendMode: blendMode !== 'normal',
isolation: isolation === 'isolate',
containerType: containerType === 'size' || containerType === 'inline-size',
willChange: willChange !== 'auto'
}
const createsStackingContext = Object.values(scenarios).some(Boolean)
return createsStackingContext
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment