Consider a very simply custom element using shadow DOM:
customElements.define('shadow-element', class ShadowElement extends HTMLElement {
constructor() {
super();
this.styleTag = document.createElement('style');
this.styleTag.textContent= `
.root::before {
content: "root here!";
color: green;
}
`
this.shadow = this.attachShadow({mode: 'closed'});
this.root = null;
}
connectedCallback() {
this.root = document.createElement('div');
this.root.className = 'root';
this.shadow.append(this.root, this.styleTag);
}
})
<shadow-element></shadow-element>
To get the CSS into the shadow DOM, I create a style
tag, which I append into the shadow root. This is all working fine so far.
Now for more complex CSS I would like to author it in a file shadow-element.css
which is in the same folder as shadow-element.js
. Besides seperation of concerns I also want IDE syntax highlighting and -completion for CSS authoring, so I really want the CSS in a separate, dedicated file.
I want to import the contents of that CSS file into a Javascript variable, like
import styles from './shadow-element.css'; // obviously doesn't work
On the project where this is being used we have a working webpack stack that allows importing CSS (and even SCSS), but unfortunately that imported CSS then becomes part of bundle.css
- which obviously is not at all useful, because the element uses shadow DOM.
Does anyone have a solution to this? I'm also open to alternative solutions, as long it won't require me to author my CSS in a .js file.
Edit: I am aware of the option of using @import './shadow-elements.css';
inside the style
tag, but I would much prefer a solution that bundles the imported CSS into my Javascript bundle (as part of the component code).
As you are using webpack, you can use raw-loader to import a text file (CSS in your case) into a string:
npm install raw-loader --save-dev
And you can use it inline in each file:
import css from 'raw-loader!./shadow-element.css';
customElements.define('shadow-element', class ShadowElement extends HTMLElement {
constructor() {
super();
this.styleTag = document.createElement('style');
this.styleTag.innerText = css;
this.shadow = this.attachShadow({mode: 'closed'});
this.root = null;
}
connectedCallback() {
this.root = document.createElement('div');
this.root.className = 'root';
this.shadow.append(this.root, this.styleTag);
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With