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