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:
To select a tag name starting with tag-name
:
/^<tag-name/.test(element.outerHTML)
@element * {
eval("/^<custom-/.test(outerHTML) && '$this'") {
border: 1px solid lime;
}
}
[test="/^<custom-/.test(this.outerHTML)"] {
border: 1px solid lime;
}
[test="/^<h[\d]/.test(this.outerHTML)"] {
color: lime;
}
[xpath="//*[starts-with(name(), 'custom-')]"] {
border: 1px solid lime;
}
[xpath="//div/*[starts-with(name(),'h')][substring(name(),2) > 0]"] {
background: red;
}