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?
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 theconstructor.You can use the
partattribute along with the::partpseudo element to allow styling from the outside.