Selecting Elements with a Partial Tag Name

CSS selectors (and document.querySelector() in JavaScript) let you select elements by matching their HTML tag name, however there’s no way to match an element based on matching only a part of the tag name. Whether working with custom elements, or wanting to write a selector encompassing <h1> tags through <h6>, being able to match a partial tag name could be really useful when writing styles.

Thankfully this is something we can do via XPath in modern browsers (>IE11) like this:

document.evaluate(
  '//*[starts-with(name(), "custom-")]',
  document, 
  null, 
  XPathResult.UNORDERED_NODE_ITERATOR_TYPE, 
  null
)

This XPath selector, //*[starts-with(name(), "custom-")], returns all nodes with a tag name that starts with custom-, so it would match <custom-tag> and <custom-example>, but not a tag named <customizer-panel>.

For those wishing to select elements in a similar way while authoring CSS, here are a few workarounds that can help:

Parts Required

JS Tests

To select a tag name starting with tag-name:

/^<tag-name/.test(element.outerHTML)

Plugins Capable

Syntax Examples

EQCSS

@element * {
  eval("/^<custom-/.test(outerHTML) && '$this'") {
    border: 1px solid lime;
  }
}

Selectory

[test="/^<custom-/.test(this.outerHTML)"] {
  border: 1px solid lime;
}
[test="/^<h[\d]/.test(this.outerHTML)"] {
  color: lime;
}

XPathy

[xpath="//*[starts-with(name(), 'custom-')]"] {
  border: 1px solid lime;
}
[xpath="//div/*[starts-with(name(),'h')][substring(name(),2) > 0]"] {
  background: red;
}

Demos