ShadowDOMのCSSスタイリング

ShadowDOMはWebComponentsの基礎技術でもあり、Javascriptを活用したコンポーネント開発の際に、理解が求められます。
ShadowDOMの最大のポイントは、ShadowRootの内外でCSSのスタイリングが隔離されているということです。

ShadowDOMへのCSSスタイル定義の基礎

ShadowDOMは多くの場合、Javascriptのコンポーネントであり、ShadowDOMへのCSSスタイリングはコンポーネントにCSSをどう追加するべきか、という問題と同じです。
以下の例はlit-htmlのコンポーネントの例です。JSXでも大きな違いはないでしょう。

const SampleComponent = () => {
  return html`
    <style>.alert { color: red }</style>
    <div class="alert">Dangerous ShadowDOM</div>
  `;
}

ShadowDOMのスタイル定義の基本形はこの通りです。要するにHTMLであり、styleタグを書くという、ある意味拍子抜けともいえる実装で構いません。
以下の変数化した例を見ると構造化についても理解できるでしょう。

const SampleComponent = () => {
  const styles = '.alert { color: red }';
  return html`
    <style>${styles}</style>
    <div class="alert">Dangerous ShadowDOM</div>
  `;
}

ShadowDOMのスタイリングをサポートするライブラリもこのような実装になっています。

デフォルト設定とカスタマイズ

ここまでのCSS定義で外界と隔離されたスタイリングは可能です。隔離されているので、原則として利用時のスタイリングの影響を受けないものと考えましょう。
ただし、利用時にカスタマイズ可能な形式で定義することは可能です。挙動が分かりやすいのは、 CSS変数による方法です。

const SampleComponent = () => {
  return html`
    <style>.alert { color: var(--alert-color, red) }</style>
    <div class="alert">Dangerous ShadowDOM</div>
  `;
}

このコード例のCSS変数のデフォルト値はredであるため、とくに指定しなければ最初の例と挙動は同じです。
利用時に外界で--alert-colorを定義してあれば、その値が採用されShadowDOMのスタイルを制御できます。

あとは、このコンポーネントのAPIとして--alert-colorが利用可能であることは自明ではないので、ドキュメント化などで利用方法を明確にしておくことが必要になるでしょう。

中馬崇尋
Chuma Takahiro