構成可能なスタイルシート

シームレスに再利用可能なスタイル。

Constructable Stylesheets は、Shadow DOM を使用する際に再利用可能なスタイルを作成して配布する方法です。

Browser Support

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 101.
  • Safari: 16.4.

Source

JavaScript を使用してスタイルシートを作成することは、これまでも可能でした。ただし、従来は document.createElement('style') を使用して <style> 要素を作成し、その sheet プロパティにアクセスして、基盤となる CSSStyleSheet インスタンスへの参照を取得していました。この方法では、CSS コードが重複して肥大化する可能性があります。また、アタッチする行為により、肥大化の有無にかかわらず、スタイルが適用されていないコンテンツが一時的に表示されることがあります。CSSStyleSheet インターフェースは、CSSOM と呼ばれる CSS 表現インターフェースのコレクションのルートです。これにより、スタイルシートをプログラムで操作する方法が提供され、古い方法に関連する問題が解消されます。

作成された CSS からインスタンス化、アプリケーションへのフローを示す図。

Constructable Stylesheets を使用すると、共有 CSS スタイルを定義して準備し、それらのスタイルを複数の Shadow Root または Document に簡単かつ重複なく適用できます。共有 CSSStyleSheet への更新は、それが採用されているすべてのルートに適用されます。また、シートが読み込まれると、スタイルシートの採用は高速かつ同期的になります。

Constructable Stylesheets によって設定された関連付けは、さまざまなアプリケーションに適しています。多くのコンポーネントで使用される一元化されたテーマを提供するために使用できます。テーマは、コンポーネントに渡される CSSStyleSheet インスタンスにすることができ、テーマの更新はコンポーネントに自動的に伝播されます。カスケードに依存せずに、CSS カスタム プロパティの値を特定の DOM サブツリーに配布するために使用できます。ブラウザの CSS パーサーへの直接インターフェースとしても使用できるため、DOM に挿入することなくスタイルシートを簡単にプリロードできます。

スタイルシートの作成

これを実現するために新しい API を導入するのではなく、Constructable StyleSheets 仕様では、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..."

構築済みスタイルシートの使用

Constructable StyleSheets で導入された 2 つ目の新機能は、Shadow Roots と Documents で利用できる 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 ソースの文字列から StyleSheet を読み込むための、新しい Promise ベースの API があります。最後に、StyleSheet のすべての使用箇所にスタイルシートの更新を適用するメカニズムがあり、テーマの変更や色の設定などを簡素化できます。

デモを見る

今後の対応

Constructable Stylesheets の初期バージョンは、ここで説明する API とともにリリースされましたが、より使いやすくするための作業が進められています。スタイルシートの挿入と削除を行う専用メソッドで adoptedStyleSheets FrozenArray を拡張する提案があります。これにより、配列のクローン作成が不要になり、スタイルシート参照の重複を回避できます。

詳細