Selecting the Ancestor of an Element

CSS is limited to selecting elements, their following (younger) siblings, and children — but is unable to select elements ‘above’ or before elements in the tree structure. CSS in browsers can’t select the parent, or ancestor of another element. There is a selector in the CSS specs called :has() which would allow you to select the ancestor of an element matching another CSS selector, but despite being in the spec for years there is currently zero browser support for :has().

Sometimes, especially when working with HTML you don’t have the ability to alter, it would be nice to be able to select an ancestor of another element for styling. While CSS is unable to work in these situations, both JavaScript and XPath are able to achieve this.

Parts Required

There are two ways you can search for ancestors of elements using JavaScript in the browser, document.closest() for matching CSS selectors, or document.evaluate() to evaluate an XPath selector that selects the ancestor of another element.

JS Tests

Closest ancestor matching CSS Selector:

element.closest(test)

Selecting and element that contains another CSS selector:

element.querySelector(test)

Syntax Examples

Selectory

Find first ancestor of id="demo" with class="target":

[test="document.querySelector('#demo').closest(test) == this"] {
  background: lime;
}

Xpathy

Find all ancestors of id="demo" that have class="target":

[xpath="//*[@id='demo']/ancestor::*[@class='target']"] {
  background: lime;
}

XPath Selector Mixin

xpath('//*[@id="demo"]/ancestor::*[@class="target"]', `
  background: lime;
`)

Plugins Capable

Demos

Further Reading