可建構的樣式表

流暢的重複使用風格

使用陰影 DOM 時,可建構的樣式表可用來建立及發布可重複使用的樣式。

瀏覽器支援

  • 73
  • 79
  • 101
  • 16.4

來源

您隨時可以使用 JavaScript 建立樣式表。不過,該程序一直都是使用 document.createElement('style') 建立 <style> 元素,然後存取其工作表屬性,以取得基礎 CSSStyleSheet 例項的參照。這個方法可能會產生重複的 CSS 程式碼及其總管,而附加程式碼會導致未設定樣式的內容閃爍 (無論內容是否膨脹)。CSSStyleSheet 介面是 CSS 表示法介面集合的根 (稱為 CSSOM),可讓您以程式輔助方式操控樣式表,並消除與舊方法相關的問題。

顯示 CSS 準備及應用方式的圖表。

可建構的樣式表可讓您定義及準備共用的 CSS 樣式,然後將這些樣式輕鬆套用至多個陰影根層級或文件,且不會重複。共用 CSSStyleSheet 的更新會套用至已採用的所有根層級,並在工作表載入後,快速並同步採用樣式表

可建構樣式表所設定的關聯,非常適合多種不同的應用程式。這可用來提供由多個元件使用的集中式主題:主題可以是 CSSStyleSheet 例項,並傳遞至元件,而主題更新會自動傳播至元件。這項功能可用來將 CSS 自訂屬性值發布至特定 DOM 子樹狀結構,而不需參考串聯。它甚至可以當做直接存取瀏覽器 CSS 剖析器的介面,可讓您輕鬆預先載入樣式表,而不必將其插入 DOM。

建構樣式表

與其導入新的 API 來完成此作業,不如導入可建構的樣式表規格,可讓您叫用 CSSStyleSheet() 建構函式以強制建立樣式表。產生的 CSSStyleSheet 物件提供兩種新方法,可在不觸發 Flash of Unstyled Content (FOUC) 的情況下,更安全地新增及更新樣式表規則。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..."

使用建構的樣式表

建構樣式工作表導入的第二項新功能是「採用樣式工作表」adoptedStyleSheets屬性,可用於陰影根層級文件。如此一來,我們就能將 CSSStyleSheet 定義的樣式明確套用至指定的 DOM 子樹狀結構。為此,我們會將屬性設為一或多個樣式表的陣列,以便套用至該元素。

// 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