可建構的樣式表

流暢的可重複使用樣式。

可建構樣式表是一種在使用 Shadow DOM 時建立及發布可重複使用樣式的方法。

Browser Support

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

Source

您一向可以使用 JavaScript 建立樣式表。不過,過去的做法是使用 document.createElement('style') 建立 <style> 元素,然後存取其工作表屬性,取得基礎 CSSStyleSheet 執行個體的參照。這種方法可能會產生重複的 CSS 程式碼和隨之而來的膨脹,而且無論是否有膨脹,附加行為都會導致未樣式內容閃爍。CSSStyleSheet 介面是 CSS 表示介面集合的根,稱為 CSSOM,提供以程式輔助方式操控樣式表,並消除與舊方法相關的問題。

這張圖表顯示從編寫 CSS 到例項化,再到套用的流程。

Constructable Stylesheets 可讓您定義及準備共用 CSS 樣式,然後輕鬆將這些樣式套用至多個 Shadow Root 或文件,且不會重複。共用 CSSStyleSheet 的更新會套用至所有已採用的根目錄,且在載入樣式表後,採用樣式表的速度很快且同步。

Constructable Stylesheets 建立的關聯非常適合多種不同的應用。這可用於提供多個元件使用的集中式主題:主題可以是傳遞至元件的 CSSStyleSheet 執行個體,主題更新會自動傳播至元件。可用於將 CSS 自訂屬性值發布至特定 DOM 子樹,而不必依賴階層。甚至可以做為瀏覽器 CSS 剖析器的直接介面,輕鬆預先載入樣式表,而不必將其插入 DOM。

建構樣式表

Constructable StyleSheets 規格可讓您透過叫用 CSSStyleSheet() 建構函式,以指令式方式建立樣式表,而不必導入新的 API 來達成此目的。產生的 CSSStyleSheet 物件有兩種新方法,可更安全地新增及更新樣式表規則,而不會觸發未套用樣式的內容閃爍 (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..."

使用建構的樣式表

Constructable StyleSheets 導入的第二項新功能是 Shadow Roots 和文件上提供的 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);

正在統整內容

有了可建構樣式表,網頁程式開發人員現在可以明確建立 CSS 樣式表,並套用至 DOM 樹狀結構。我們推出新的 Promise 型 API,可從使用瀏覽器內建剖析器和載入語意的 CSS 來源字串載入 StyleSheet。最後,我們提供了一種機制,可將樣式表更新套用至 StyleSheet 的所有用途,簡化主題變更和顏色偏好設定等作業。

觀看示範影片

展望未來

Constructable Stylesheets 的初始版本隨附此處所述的 API,但我們正在努力讓使用方式更簡單。目前有一項提案,建議使用專屬方法擴充 adoptedStyleSheets FrozenArray,以便插入及移除樣式表,這樣就不需要複製陣列,也能避免潛在的重複樣式表參照。

更多資訊