スタイル

コンポーネントのテンプレートは、そのシャドウルートにレンダリングされます。コンポーネントに追加するスタイルは、シャドウルートに自動的にスコープされ、コンポーネントのシャドウルート内の要素のみに影響します。

Shadow DOM は、スタイルの強力なカプセル化を提供します。Lit が Shadow DOM を使用しなかった場合、コンポーネントの外側の要素(コンポーネントの祖先または子)を誤ってスタイル設定しないように、非常に注意する必要があります。これには、長く扱いにくいクラス名を書くことが含まれる場合があります。Shadow DOM を使用することで、Lit は、記述するセレクターが Lit コンポーネントのシャドウルート内の要素のみに適用されるように保証します。

スコープ付きスタイルは、タグ付きテンプレートリテラル `css` 関数を使用して、静的な `styles` クラスフィールドで定義します。このようにスタイルを定義すると、最適なパフォーマンスが得られます。

コンポーネントに追加するスタイルは、Shadow DOM を使用してスコープされます。概要については、Shadow DOM を参照してください。

静的な `styles` クラスフィールドの値は、次のようになります。

  • 単一のタグ付きテンプレートリテラル。

  • タグ付きテンプレートリテラルの配列。

静的な `styles` クラスフィールドは、ほとんどの場合、コンポーネントにスタイルを追加する最良の方法ですが、この方法では処理できないユースケースもあります。たとえば、インスタンスごとにスタイルをカスタマイズする場合などです。スタイルを追加する他の方法については、テンプレート内でのスコープ付きスタイルの定義 を参照してください。

静的スタイルは、コンポーネントのすべてのインスタンスに適用されます。CSS 内の式は、**1 回**評価され、すべてのインスタンスで再利用されます。

ツリーベースまたはインスタンスごとのスタイルのカスタマイズには、CSS カスタムプロパティを使用して、要素をテーマ設定できるようにします。

Lit コンポーネントが潜在的に悪意のあるコードを評価するのを防ぐため、`css` タグは、それ自体が `css` タグ付き文字列または数値である入れ子になった式のみを許可します。

この制限は、URL パラメーターやデータベース値など、信頼できないソースから悪意のあるスタイル、または悪意のあるコードが注入される可能性のあるセキュリティの脆弱性からアプリケーションを保護するためです。

それ自体が `css` リテラルではない式を `css` リテラルで使用しなければならない場合、**および**その式が独自のコードで定義された定数など、完全に信頼できるソースからのものであると確信している場合は、式を `unsafeCSS` 関数でラップできます。

**信頼できる入力でのみ `unsafeCSS` タグを使用してください。** サニタイズされていない CSS を注入すると、セキュリティリスクになります。たとえば、悪意のある CSS は、サードパーティのサーバーを指す画像 URL を追加することで「外部に連絡」する可能性があります。

タグ付きテンプレートリテラルの配列を使用すると、コンポーネントはスーパークラスからスタイルを継承し、独自のスタイルを追加できます。

JavaScript でスーパークラスの styles プロパティを参照するには、`super.styles` を使用することもできます。TypeScript を使用している場合は、コンパイラが常に正しく変換するわけではないため、`super.styles` の使用は避けることをお勧めします。例に示すように、スーパークラスを明示的に参照することで、この問題を回避できます。

TypeScript でサブクラス化されることを意図したコンポーネントを作成する際には、`styles` を配列でオーバーライドできるように、`static styles` フィールドを `CSSResultGroup` として明示的に型指定する必要があります。

タグ付きスタイルをエクスポートするモジュールを作成することで、コンポーネント間でスタイルを共有できます。

要素は、スタイルをインポートし、静的な `styles` クラスフィールドに追加できます。

CSS の Unicode エスケープシーケンスは、バックスラッシュの後に 4 桁または 6 桁の 16 進数が続きます。たとえば、箇条文字には `\2022` を使用します。これは、JavaScript の非推奨の8 進数エスケープシーケンスの形式に似ているため、`css` タグ付きテンプレートリテラルでこれらのシーケンスを使用すると、エラーが発生します。

スタイルに Unicode エスケープを追加するための回避策が 2 つあります。

  • 2 番目のバックスラッシュを追加します(たとえば、`\\2022`)。
  • `\u` で始まる JavaScript エスケープシーケンスを使用します(たとえば、`\u2022`)。

このセクションでは、Shadow DOM スタイルの概要を簡単に説明します。

コンポーネントに追加するスタイルは、次の要素に影響を与える可能性があります。

Lit テンプレートは、デフォルトでシャドウツリーにレンダリングされます。要素のシャドウツリーにスコープされたスタイルは、メインドキュメントや他のシャドウツリーには影響しません。同様に、継承された CSS プロパティ を除いて、ドキュメントレベルのスタイルは、シャドウツリーの内容には影響しません。

標準の CSS セレクターを使用する場合、それらはコンポーネントのシャドウツリー内の要素のみに一致します。つまり、ページの他の部分を誤ってスタイル設定する心配がないため、多くの場合、非常に単純なセレクターを使用できます。たとえば、`input`、`*`、または `#my-element` などです。

特別な `:host` セレクターを使用して、コンポーネント自体のスタイルを設定できます。(シャドウツリーを所有または「ホスト」する要素は、ホスト要素と呼ばれます。)

ホスト要素のデフォルトスタイルを作成するには、`:host` CSS擬似クラスと `:host()` CSS擬似クラス関数を使用します。

  • `:host` はホスト要素を選択します。
  • `:host(selector)` はホスト要素を選択します。ただし、ホスト要素がselectorと一致する場合のみです。

ホスト要素は、シャドウツリーの外側のスタイルによっても影響を受ける可能性があるため、` :host` と `:host()` ルールで設定するスタイルは、ユーザーがオーバーライドできるデフォルトスタイルとして考慮する必要があります。たとえば

コンポーネントは子要素を受け入れることができます(`

    ` 要素は `
  • ` 子要素を持つことができます)。子要素をレンダリングするには、スロット要素で子要素をレンダリングする に記載されているように、テンプレートに 1 つ以上の `` 要素を含める必要があります。

    `` 要素は、ホスト要素の子要素が表示されるシャドウツリー内のプレースホルダーとして機能します。

    `::slotted()` CSS擬似要素を使用して、`` を介してテンプレートに含まれる子要素を選択します。

    • `::slotted(*)` は、すべてのスロット要素に一致します。
    • `::slotted(p)` は、スロットされた段落に一致します。
    • `p ::slotted(*)` は、`` が段落要素の子孫であるスロット要素に一致します。

    **直接スロットされた子要素のみ**が `::slotted()` でスタイル設定できることに注意してください。

    また、子要素はシャドウツリーの外側からスタイル設定できるため、`::slotted()` スタイルは、オーバーライドできるデフォルトスタイルとして扱う必要があります。

    **ShadyCSS ポリフィルにおけるスロットされたコンテンツの制限。** ポリフィルに適した方法で `::slotted()` 構文を使用する方法の詳細については、ShadyCSS の制限 を参照してください。

    最適なパフォーマンスを得るには、静的なstylesクラスフィールドの使用をお勧めします。ただし、Litテンプレートでスタイルを定義したい場合もあるでしょう。テンプレートにスコープ付きスタイルを追加するには、2つの方法があります。

    これらの手法にはそれぞれ長所と短所があります。

    通常、スタイルは静的なstylesクラスフィールドに配置されます。ただし、要素の静的なstylesは**クラスごとに1回**評価されます。場合によっては、**インスタンスごとに**スタイルをカスタマイズする必要があるかもしれません。これには、CSSプロパティを使用してテーマ可能な要素を作成することをお勧めします。または、Litテンプレートに<style>要素を含めることもできます。これらはインスタンスごとに更新されます。

    **ShadyCSSポリフィルにおけるインスタンスごとのスタイルに関する制限事項。**インスタンスごとのスタイルは、ShadyCSSポリフィルを使用する場合はサポートされていません。ShadyCSSの制限事項を参照して詳細を確認してください。

    スタイル要素内で式を使用することには、いくつかの重要な制限事項とパフォーマンスの問題があります。

    **ShadyCSSポリフィルにおける式に関する制限事項。**ShadyCSSポリフィルの制限により、<style>要素内の式はShadyCSSではインスタンスごとに更新されません。さらに、ShadyCSSポリフィルを使用する場合は、<style>ノードを式の値として渡すことができない場合があります。ShadyCSSの制限事項で詳細情報を確認してください。

    <style>要素内で式を評価することは非常に非効率です。<style>要素内のテキストが変更されると、ブラウザは<style>要素全体を再解析する必要があり、不要な作業が発生します。

    このコストを軽減するために、インスタンスごとの評価が必要なスタイルとそうでないスタイルを分離します。

    外部スタイルシートのインポート(推奨されません)

    “外部スタイルシートのインポート(推奨されません)”へのパーマリンク

    <link>を使用してテンプレートに外部スタイルシートを含めることができますが、このアプローチはお勧めしません。代わりに、スタイルは静的なstylesクラスフィールドに配置する必要があります。

    外部スタイルシートに関する注意点。

    • ShadyCSSポリフィルは外部スタイルシートをサポートしていません。
    • 外部スタイルは、読み込み中にスタイルが適用されていないコンテンツのちらつき(FOUC)を引き起こす可能性があります。
    • href属性のURLは、**メインドキュメント**に対する相対パスです。アプリを構築していてアセットのURLが既知の場合は問題ありませんが、再利用可能な要素を構築する際には、外部スタイルシートの使用を避けてください。

    スタイルを動的にするための1つの方法は、テンプレートのclass属性またはstyle属性に式を追加することです。

    Litは、HTMLテンプレートにクラスとスタイルを簡単に適用するための、classMapstyleMapの2つのディレクティブを提供しています。

    これらのディレクティブやその他のディレクティブの詳細については、組み込みディレクティブに関するドキュメントを参照してください。

    styleMapおよび/またはclassMapを使用するには

    1. classMapおよび/またはstyleMapをインポートします。

    2. 要素テンプレートでclassMapおよび/またはstyleMapを使用します。

    詳細については、classMapstyleMapを参照してください。

    CSS継承CSS変数とカスタムプロパティを組み合わせて使用することで、テーマ可能な要素を簡単に作成できます。CSSセレクタを適用してCSSカスタムプロパティをカスタマイズすることにより、ツリーベースおよびインスタンスごとのテーマ設定を簡単に適用できます。例を以下に示します。

    CSS継承により、親要素とホスト要素は特定のCSSプロパティを子孫要素に伝播できます。

    すべてのCSSプロパティが継承されるわけではありません。継承されるCSSプロパティには以下が含まれます。

    • color
    • font-familyおよびその他のfont-*プロパティ
    • すべてのCSSカスタムプロパティ(--*

    詳細については、MDNのCSS継承を参照してください。

    祖先要素で設定されたスタイルを、その子孫要素が継承するようにCSS継承を使用できます。

    すべてのCSSカスタムプロパティ(--custom-property-name)は継承されます。これを使用して、コンポーネントのスタイルを外部から構成できます。

    次のコンポーネントは、背景色をCSS変数に設定します。CSS変数は、DOMツリー内の祖先と一致するセレクタによって設定されている場合は--my-backgroundの値を使用し、それ以外の場合はyellowをデフォルト値として使用します。

    このコンポーネントのユーザーは、my-elementタグをCSSセレクタとして使用して、--my-backgroundの値を設定できます。

    --my-backgroundは、my-elementのインスタンスごとに構成可能です。

    詳細については、MDNのCSSカスタムプロパティを参照してください。