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

シームレスに再利用できるスタイル。

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

対応ブラウザ

  • 73
  • 79
  • 101
  • 16.4

ソース

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

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

構成可能なスタイルシートを使用すると、共有 CSS スタイルを定義して準備し、それらのスタイルを複数のシャドウルートやドキュメントに簡単に適用できます。共有された CSSStyleSheet の更新は、それが導入されているすべてのルートに適用されます。スタイルシートの導入は、シートが読み込まれると高速かつ同期されます。

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

スタイルシートの作成

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

作成されたスタイルシートの使用

Constructable StyleSheets で導入された 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);

Putting it all together

With Constructable StyleSheets, web developers now have an explicit solution for creating CSS StyleSheets and applying them to DOM trees. We have a new Promise-based API for loading StyleSheets from a string of CSS source that uses the browser's built-in parser and loading semantics. Finally, we have a mechanism for applying stylesheet updates to all usages of a StyleSheet, simplifying things like theme changes and color preferences.

View Demo

Looking ahead

The initial version of Constructable Stylesheets shipped with the API described here, but there's work underway to make things easier to use. There's a proposal to extend the adoptedStyleSheets FrozenArray with dedicated methods for inserting and removing stylesheets, which would obviate the need for array cloning and avoid potential duplicate stylesheet references.

More information