2023年6月8日木曜日

HTML 全体の CSS を取得して Shadow DOM に適用する

以下のコードで HTML 全体の CSS を取得して Shadow DOM に適用することができます。

最近まで replaceSync() と adoptedStyleSheets() の存在を知らなかったのですが、 この 2つを使うと毎回 style タグを書き出すより効率的に処理できるらしい。

これまで Shadow DOM の中に link タグを書くような方法を使っていたのですが、link タグだと最適化がしにくい問題があります。 CSS はインライン化したほうが高速なので、その時にも同じように使える方法が欲しかったのですが、この方法でいけるとわかりました。 document.styleSheets も知らなかった…。
function getGlobalCSS() {
  let cssText = "";
  for (const stylesheet of document.styleSheets) {
    for (const rule of stylesheet.cssRules) {
      cssText += rule.cssText;
    }
  }
  const css = new CSSStyleSheet();
  css.replaceSync(cssText);
  return css;
}

const globalCSS = getGlobalCSS();

class TestBox extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.adoptedStyleSheets = [globalCSS];

    const template = document.getElementById("test-box")
      .content.cloneNode(true);
    this.shadowRoot.appendChild(template);
  }
}
customElements.define("test-box", TestBox);
どんな状況でも使えるのでかなり便利なテクニックです。

0 件のコメント: