シームレスに再利用可能なスタイル
構築可能なスタイルシートは、Shadow DOM の使用時に再利用可能なスタイルを作成して配布する方法です。
これまでも、JavaScript を使用してスタイルシートを作成することは可能でした。ただしこれまでは、document.createElement('style')
を使用して <style>
要素を作成し、そのシート プロパティにアクセスして、基盤となる CSSStyleSheet インスタンスへの参照を取得していました。この方法では、CSS コードが重複し、それに付随する肥大化が生じる可能性があり、肥大化の有無にかかわらず、スタイルのないコンテンツのフラッシュにつながることがあります。CSSStyleSheet
インターフェースは CSSOM と呼ばれる CSS 表現インターフェースのコレクションのルートです。スタイルシートをプログラムで操作する手段を提供するとともに、従来の方法に伴う問題を解消します。
構築可能なスタイルシートを使用すると、共有 CSS スタイルを定義して準備し、それらのスタイルを複数の Shadow Root や Document に複製することなく簡単に適用できます。共有された CSSStyleSheet に対する更新は、それが取り込まれているすべてのルートに適用されます。また、シートが読み込まれると、スタイルシートの取り込みが高速かつ同期的に行われます。
構築可能スタイルシートで設定された関連付けは、さまざまな用途に適しています。これは、多くのコンポーネントで使用される一元化されたテーマを提供するために使用できます。テーマは、コンポーネントに渡される CSSStyleSheet
インスタンスで、テーマの更新は自動的にコンポーネントに伝播されます。カスケードに依存せずに、CSS カスタム プロパティの値を特定の DOM サブツリーに割り当てることができます。また、ブラウザの CSS パーサーへの直接インターフェースとして使用でき、スタイルシートを DOM に挿入しなくても簡単にプリロードできます。
スタイルシートを作成する
Constructable StyleSheets の仕様では、これを行うための新しい API を導入するのではなく、CSSStyleSheet()
コンストラクタを呼び出すことで、命令的にスタイルシートを作成できます。作成された CSSStyleSheet オブジェクトには、Flash of Unstyled Content(FOUC)をトリガーせずに、より安全にスタイルシート ルールを追加および更新できる 2 つの新しいメソッドが追加されます。
replace()
メソッドと replaceSync()
メソッドは、スタイルシートを CSS の文字列に置き換え、replace()
は Promise を返します。どちらの場合も、外部スタイルシート参照はサポートされていません。@import
ルールは無視され、警告が生成されます。
const sheet = new CSSStyleSheet();
// replace all styles synchronously:
sheet.replaceSync('a { color: red; }');
// replace all styles:
sheet.replace('a { color: blue; }')
.then(() => {
console.log('Styles replaced');
})
.catch(err => {
console.error('Failed to replace styles:', err);
});
// Any @import rules are ignored.
// Both of these still apply the a{} style:
sheet.replaceSync('@import url("styles.css"); a { color: red; }');
sheet.replace('@import url("styles.css"); a { color: red; }');
// Console warning: "@import rules are not allowed here..."
作成されたスタイルシートの使用
構成可能な StyleSheets によって導入された 2 つ目の新機能は、Shadow Roots とドキュメントで利用できる adoptedStyleSheets プロパティです。これにより、CSSStyleSheet
で定義されたスタイルを特定の DOM サブツリーに明示的に適用できます。そのためには、その要素に適用する 1 つ以上のスタイルシートの配列をプロパティに設定します。
// Create our shared stylesheet:
const sheet = new CSSStyleSheet();
sheet.replaceSync('a { color: red; }');
// Apply the stylesheet to a document:
document.adoptedStyleSheets.push(sheet);
// Apply the stylesheet to a Shadow Root:
const node = document.createElement('div');
const shadow = node.attachShadow({ mode: 'open' });
shadow.adoptedStyleSheets.push(sheet);
すべてを組み合わせる
ウェブ デベロッパーは、Constructable StyleSheets を使用して、CSS スタイルシートを作成して DOM ツリーに適用するための明示的なソリューションを利用できるようになります。ブラウザの組み込みパーサーを使用してセマンティクスを読み込み、CSS ソースの文字列からスタイルシートを読み込むための、新しい Promise ベースの API が用意されています。最後に、スタイルシートのすべての使用にスタイルシートの更新を適用するメカニズムを用意し、テーマの変更や色の設定などを簡素化しています。
今後に向けて
構築可能スタイルシートの初期バージョンは、ここで説明する API とともに出荷されましたが、使いやすさを向上させるための作業が進行中です。スタイルシートを挿入および削除する専用メソッドで adoptedStyleSheets
FrozenArray を拡張する提案があります。これにより、配列をクローニングする必要がなく、スタイルシート参照の重複を回避できます。