CSS スタイルシートによるコンポーネントのスタイル設定

コンポーネントに一連のスタイルをバンドルするには、コンポーネントと同じ名前のスタイルシートをコンポーネントのフォルダに作成します。スタイルシートは自動的にコンポーネントに適用されます。1 つ以上のスタイルシートを使用してコンポーネントのスタイルを設定する場合は、静的プロパティの stylesheets を設定します。

コンポーネントのフォルダには、スタイルシートを 1 つだけ含めることができます。スタイルシートでは標準の CSS 構文が使用されるため、ほとんどのセレクタを使用できます。スタイルシートは、複数の CSS モジュールからスタイルルールをインポートできます。

コンポーネントのスタイルシートで定義されたスタイルの範囲はそのコンポーネントに限定されます。このルールにより、コンポーネントをそのスタイルを失うことなく異なるコンテキストで再利用できます。また、ページの他の部分のスタイルがコンポーネントのスタイルによって上書きされるのを防ぎます。

この例は、親コンポーネントで定義された CSS スタイルが子に到達しないしくみを示しています。c-parentc-child の 2 つのコンポーネントがあります。各コンポーネントには <h1> タグが含まれます。parent.css スタイルシートでは h1 スタイルが xx-large として定義されます。コードを実行すると、スタイルは親の <h1> タグにのみ適用され、ネストされた子の <h1> タグには適用されません。

1<!-- parent.html -->
2<template>
3  <h1>To Do List (h1)</h1>
4  <c-child></c-child>
5</template>
1/* parent.css */
2h1 {
3  font-size: xx-large;
4}
1<!-- child.html -->
2<template>
3  <h1>To Do Item (h1)</h1>
4</template>

親のテキストは特大です。子のテキストは通常サイズです。

親コンポーネントは子コンポーネントをスタイル設定できますが、子コンポーネントを 1 つの要素としてスタイル設定します。親は子に到達できません。c-child セレクタを、子コンポーネントの周囲の境界線を定義する parent.css に追加しましょう。

1/* parent.css */
2h1 {
3  font-size: xx-large;
4}
5
6c-child {
7  display: block;
8  border: 2px solid red;
9}

子コンポーネントは赤いボックスで囲まれています。

では、c-child コンポーネントをその独自のスタイルシート child.css からスタイル設定しましょう。

セレクタを child.css に追加する前に、c-child セレクタを parent.css から削除して赤いボックスを削除しましょう。コンポーネントとその親の両方からコンポーネントをスタイル設定することはお勧めしません。混乱し、予期しない結果が生じる可能性があります。次の parent.cssc-child は削除されています。

1/* parent.css */
2h1 {
3  font-size: xx-large;
4}

コンポーネントのスタイルシートはその独自の要素 (この例では c-child) に到達し、その要素をスタイル設定できます。

c-child セレクタを使用する代わりに :host セレクタを使用します。

1/* child.css */
2:host {
3  display: block;
4  background: yellow;
5}

子コンポーネントの背景は黄色です。

:host を使用してホスト要素を対象とすることで、child.css からスタイルを <c-child> に適用しました。

:host セレクタは、省略可能なセレクタリストを受け入れます。一致するには、渡されたセレクタに一致するクラスがホスト要素に必要です。:host セレクタのしくみを確認するため、サンプルコードを書き換えて、もう少し実際のアプリケーションのようにしましょう。[ToDo リスト] の項目の名前を渡すことができるように <slot>c-child に追加します。

1<!-- child.html -->
2<template>
3  <h1>To Do Item</h1>
4  <slot></slot>
5</template>

子コンポーネントの h1 をスタイル設定しましょう。ただし、サイズは large にします。これは、親コンポーネントで定義した xx-large h1 よりも少し小さいサイズです。また、有効な項目を除いてすべてのリスト項目をライトグレーにしましょう。有効な項目はライトグリーンです。

1/* child.css */
2h1 {
3  font-size: large;
4}
5:host {
6  display: block;
7  background: lightgray;
8}
9
10:host(.active) {
11  background-color: lightgreen;
12}

親に 3 つの c-child コンポーネントを追加し、その 1 つを有効にしましょう。実際のアプリケーションでは、有効なコンポーネントは、選択された項目です。

1<!-- parent.html -->
2<template>
3  <h1>To Do List</h1>
4  <c-child>Buy potatoes</c-child>
5  <c-child>Donate to a good cause</c-child>
6  <c-child class="active">Plan a party</c-child>
7</template>
1/* parent.css */
2
3h1 {
4  font-size: xx-large;
5}

有効な To Do 項目がライトグリーンで表示されている To Do リスト。

CSS サポートおよびパフォーマンスへの影響 

CSS 範囲指定は、次のいくつかの例外を除き、CSS Scoping Module Level 1 (CSS 範囲指定モジュールレベル 1) 標準に一致します。

  • :host-context() 疑似クラス関数はサポートされません。
  • ::part 疑似要素はサポートされません。
  • CSS 内の ID セレクタはサポートされません。id 値が HTML テンプレート内で一意であるようにします。テンプレートを表示するときに、id 値が、グローバル一意値に変換される場合があります。CSS 内で ID セレクタを使用すると、変換された ID に一致しなくなります。
  • LWC では、コンポーネントのカスタム公開プロパティは、対応する HTML 属性に反映されません。スタイル設定用の ID を子要素に与えるには、class 属性または data-* 属性を使用します。

範囲設定された CSS はパフォーマンスに影響するため、注意して使用してください。各セレクタチェーンは範囲設定され、:host() に渡された各複合式は複数のセレクタに分散します。この変換によって、生成された CSS のサイズと複雑さが増します。また、それらが増すことにより、解析時間が長くなり、スタイルの再計算時間が長くなります。

CSS を確実にカプセル化するため、各要素に追加の属性が含まれますが、これによっても表示時間が長くなります。たとえば、<c-parent> 要素には c-parent_parent-host 属性があります。

1<c-parent c-parent_parent-host>
2  <h1 c-parent_parent>To Do List</h1>
3  <c-child c-parent_parent c-child_child-host>
4    <h1 c-child_child>To Do Item</h1>
5  </c-child>
6  <c-child class="active" c-parent_parent c-child_child-host>
7    <h1 c-child_child>To Do Item</h1>
8  </c-child>
9</c-parent>

コンポーネントへの CSS スタイルシートの割り当て 

1 つ以上のスタイルシートを使用してコンポーネントをカスタマイズするには、stylesheets 静的プロパティを LightningElement コンストラクタに追加します。このプロパティはスタイルシートの配列を受け入れ、そのデフォルト値は空の配列です。stylesheets プロパティは、Light DOM コンポーネントと Shadow DOM コンポーネントに設定できます。

例えば、スタイルシートの header-styles.cssbutton-styles.cssmyComponent に挿入するには、myComponent.jsstylesheets 静的プロパティを設定します。

1myComponent/
2    ├── myComponent.js
3    ├── myComponent.html
4    ├── myComponent.css
5    ├── header-styles.css
6    └── button-styles.css
1// myComponent.js
2import { LightningElement } from 'lwc';
3import headerStyles from './header-styles.css';
4import buttonStyles from './button-styles.css';
5
6export default Example class extends LightningElement {
7    static stylesheets = [
8        headerStyles,
9        buttonStyles
10    ];
11}

LWC エンジンが最初に挿入するスタイルシートは myComponent.css です。このスタイルシートはコンポーネントのテンプレートに暗黙的に関連付けられているためです。次にエンジンは、stylesheets プロパティに関連付けられているすべてのスタイルシートを、配列内に示されている順序で読み込みます。stylesheets のこの設定に基づいて、myComponent はそのスタイルシートを myComponent.cssheader-styles.cssbutton-styles.css の順序で読み込みます。

LWC エンジンは、コンポーネントクラスの定義時にアプリケーションのライフタイムの stylesheets 配列をキャッシュします。コンポーネントのコードが評価された後に stylesheets を変更しても、挿入されたスタイルシートへの影響はありません。

サブクラスコンポーネントは、スーパークラスコンポーネントから stylesheets を自動的に継承しません。スーパークラスコンポーネントの stylesheets をサブクラスコンポーネントに拡張する場合は、super.stylesheets を使用して、スーパークラスの stylesheets をサブクラスコンポーネントのスタイルシートに手動でマージします。

1import { LightningElement } from "lwc";
2import superclassStylesheet from "./superclass.css";
3import subclassStylesheet from "./subclass.css";
4
5class Superclass extends LightningElement {
6  static stylesheets = [superclassStylesheet];
7}
8
9class Subclass extends Superclass {
10  static stylesheets = [...super.stylesheets, subclassStylesheet];
11}

関連トピック

The Japanese Summer '24 guide is now live

日本語の Summer '24 ガイドが公開されました! 「Component Reference (コンポーネントリファレンス)」は、以前と同様にコンポーネントライブラリにあります。