Ancestor Selector Mixin

This mixin lets CSS authors apply styles to all ancestor elements matching a CSS selector to another element matching a given CSS selector. You can use this to style all matching ancestors.

Syntax

ancestor(selector, ancestor, rule)

Example

Input:

ancestor('#start', '.target', `border-color: lime`)

Output:

/* #start:ancestor(.target) */
[data-ancestor-unique="0"] {
  border-color: lime;
}

Code

function ancestor(selector, ancestor, rule) {

  var tag = document.querySelectorAll(ancestor)
  var style = ''
  var count = 0

  for (var i=0; i<tag.length; i++) {

    var descendant = tag[i].querySelector(selector)

    if (descendant) {

      var attr = (selector+ancestor).replace(/\W+/g, '')

      tag[i].setAttribute('data-ancestor-' + attr, count)

      style += '\n/* ' + selector + ':ancestor(' + ancestor + ') */\n'
             + '[data-ancestor-' + attr + '="' + count + '"] {\n'
             + '  ' + rule + '\n'
             + '}\n'

      count ++

    }

  }

  return style

}

Techniques Capable