CSSStyleSheet - programatic vs <style>

by Alex Phillips

HTML

<button>TEST BUTTON</button>

JavaScript

// const styles = `button { 
//   text-decoration: underline;
//   text-decoration-thickness: 1px;
// }`;
const styles = `
  :root,
  :host {
    --decoration: none;
    --hover-decoration: underline;
    --hover-thickness: 1px;
  }
  button {
    text-decoration: var(--decoration);
  }
  button:hover {
    text-decoration: var(--hover-decoration);
    text-decoration-thickness: var(--hover-thickness);
  }
`;

class CustomButton extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML = `<button>TEST BUTTON SHADOW</button>`;
  }
}
customElements.define('custom-button', CustomButton);

Promise.all([
  (async () => {
    const styleSheet = new CSSStyleSheet();
    await styleSheet.replace(styles);
    return styleSheet;
  })(),
  new Promise((resolve) => {
    const el = document.createElement('style');
    el.append(styles);
    el.addEventListener('load', (e) => resolve(el.sheet));
    document.body.append(el);
  }),
  (async () => {
    const styleSheet = new CSSStyleSheet();
    await styleSheet.replace(styles);
    const button = document.createElement('custom-button');
    button.shadowRoot.adoptedStyleSheets.push(styleSheet);
    document.body.append(button);
    return styleSheet;
  })()
]).then((sheets) => {
  sheets.forEach((el) => console.log(el.cssRules[2].cssText));
});