Antrikshy
Antrikshy

Reputation: 3106

Why can't I target my custom-defined HTML elements in CSS?

In my HTML, I've got:

<link rel="stylesheet" href="css/styles.css">
<script src="js/components/custom.js"></script> 
...
<custom></custom>

In custom.js, say I've defined:

class Custom extends HTMLElement {
  connectedCallback() {
  const shadow = this.attachShadow({mode: 'open'});
    shadow.innerHTML = `
      <style>
        @import url('/css/styles.css');
      </style>
      ...
    `
  }
}

customElements.define('custom', Custom)

In styles.css, when I define styles, they work. But I can't do something like

custom img {

}

to target an img inside custom. I have to use wrappers like div.custom-contents to target elements within.

Is this a known limitation perhaps with @imports like this, custom elements in general, or am I doing something wrong?

Upvotes: 1

Views: 1122

Answers (1)

connexo
connexo

Reputation: 56754

It is mandatory for custom elements that the name must consist of at least one letter, followed by a - dash, then at least one other letter. Your web component will not work if you don't conform to that requirement.

Your component uses shadow DOM. No outside styles affect the shadow DOM (other than inheritance), and no styles in the shadow DOM affect elements outside of of your component. This is the main concept behind shadow DOM - components bring their styling, and don't affect other elements on the page they're used in.

Also, you shouldn't attach the shadow DOM in the connectedCallback. That should always be done in the constructor.

You can use the part attribute along with the ::part pseudo element to allow styling from the outside.

Upvotes: 2

Related Questions