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

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

コンストラクタブル スタイルシートは、シャドー DOM を使用するときに、再利用可能なスタイルを作成して配布する方法です。

対応ブラウザ

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

ソース

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

CSS の準備と適用を示す図。

コンストラクタブル スタイルシートを使用すると、共有 CSS スタイルを定義して準備し、それらのスタイルを複数のシャドウルートまたはドキュメントに簡単に重複なく適用できます。共有 CSSStyleSheet の更新は、それがアドプトされているすべてのルートに適用されます。スタイルシートのアドプトは、シートが読み込まれると高速で同期的に実行されます。

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

スタイルシートの作成

これを実現するために新しい API を導入するのではなく、Constructable StyleSheets 仕様では、CSSStyleSheet() コンストラクタを呼び出してスタイルシートを命令的に作成できます。生成された CSSStyleSheet オブジェクトには、スタイル設定されていないコンテンツのフラッシュ(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..."

作成されたスタイルシートを使用する

コンストラクタブル スタイルシートで導入された 2 つ目の新機能は、シャドウルートドキュメントで利用可能な 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);

すべてを組み合わせる

コンストラクタブル スタイルシートにより、ウェブ デベロッパーは CSS スタイルシートを作成して DOM ツリーに適用するための明示的なソリューションを利用できるようになります。ブラウザの組み込みパーサーと読み込みセマンティクスを使用して、CSS ソースの文字列から StyleSheet を読み込むための新しい Promise ベースの API が導入されました。最後に、StyleSheet のすべての使用箇所にスタイルシートの更新を適用するメカニズムがあり、テーマの変更や色の設定などを簡素化できます。

デモを見る

今後に向けて

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

詳細