Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Element Selector

Is there a way to select all custom elements with CSS? I want to make all custom elements block elements by default (most browsers make them inline by default), and then override this as necessary.

My rule may look something like this:

*::custom {
    display: block;
}

All custom elements have dashes in the standard, so I could create a rule taking advantage of that, but it would be slower on many/most current browsers, as it would need to use regular expressions. If there were a built-in selector, this would probably be faster.

like image 540
trysis Avatar asked Jul 17 '15 16:07

trysis


4 Answers

No, there isn't a pseudo selector to do that.

One certainly not optimal solution, however, would be to use this type of CSS:

:not(html, head, body, h1, h2, h3, h4, h5, h6, div, ...) {
  /* Code here */
}

It would work! On the down side if ever new elements are added you need to add that element into your not-selector. Yay.

^.^

like image 108
Florrie Avatar answered Oct 19 '22 14:10

Florrie


Add an inert custom attribute to your custom elements:

<some-element cutom-elem /> <other-element custom-elem />
<script> 
  var customs = document.querySelectorAll( "*[custom-elem]" )
</script>
<style>
    *[custom-elem] { display: block ; }
</style>
like image 30
Supersharp Avatar answered Oct 19 '22 13:10

Supersharp


Here's a workaround based on Florrie's answer: :not(html):not(head):not(title):not(base):not(link):not(meta):not(style):not(body):not(article):not(section):not(nav):not(aside):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(hgroup):not(header):not(footer):not(address):not(p):not(hr):not(pre):not(blockquote):not(ol):not(ul):not(li):not(dl):not(dt):not(dd):not(figure):not(figcaption):not(div):not(main):not(a):not(em):not(strong):not(small):not(s):not(cite):not(q):not(dfn):not(abbr):not(data):not(time):not(code):not(var):not(samp):not(kbd):not(sub):not(sup):not(i):not(b):not(u):not(mark):not(ruby):not(rb):not(rt):not(rtc):not(rp):not(bdi):not(bdo):not(span):not(br):not(wbr):not(ins):not(del):not(picture):not(img):not(iframe):not(embed):not(object):not(param):not(video):not(audio):not(source):not(track):not(map):not(area):not(math):not(svg):not(table):not(caption):not(colgroup):not(col):not(tbody):not(thead):not(tfoot):not(tr):not(td):not(th):not(form):not(label):not(input):not(button):not(select):not(datalist):not(optgroup):not(option):not(textarea):not(keygen):not(output):not(progress):not(meter):not(fieldset):not(legend):not(script):not(noscript):not(template):not(canvas)

Additionally, you will have to account for SVG and MathML namespaces.

  • One way would be to just add their tags in a similar manner.
  • In some cases (ad-blocking), it might be sufficient to prepend that selector with a few possible parents to avoid <svg> and <math> children. Something like :-webkit-any(body, div) > :not(.... See :is(), :matches(), :any().
  • Once implemented, Selectors Level 4 should allow something like :not(math *, svg *).
  • @namespace can be used, something like @namespace xhtml "http://www.w3.org/1999/xhtml"; xhtml|*:not(....
like image 3
Abradoks Avatar answered Oct 19 '22 14:10

Abradoks


You could do this using slightly modified code from this answer to get all registered custom tag names:

function getCustomElements() {
    const allElems = document.getElementsByTagName("*");
    let elementNames = [].map.call(allElems, el => el.nodeName.toLowerCase())
    elementNames = [...new Set(elementNames)];
    return elementNames.filter(name => customElements.get(name));
}

Which you can then use to style all custom elements:

const customElementSelector = getCustomElements().join();
document.querySelectorAll(customElementSelector).forEach(el => {
    el.style.border = "solid";
});
like image 1
Tentacola Avatar answered Oct 19 '22 13:10

Tentacola