可构造的样式表

样式支持无缝重复使用。

可构造的样式表是在使用 Shadow DOM 时创建和分发可重复使用的样式的方法。

浏览器支持

  • 73
  • 79
  • 101
  • 16.4

来源

一直以来,都可以使用 JavaScript 创建样式表。不过,历来都是使用 document.createElement('style') 创建 <style> 元素的过程,然后访问其工作表属性,获取对底层 CSSStyleSheet 实例的引用。这种方法可能会产生重复的 CSS 代码及其相应的膨胀,并且附加行为会导致一闪而过没有样式的内容(无论是否存在膨胀)。CSSStyleSheet 接口是 CSS 表示法接口集合(称为 CSSOM)的根,提供了一种编程方式来操控样式表,同时消除了与旧方法相关的问题。

展示 CSS 准备和应用的示意图。

借助可构造的样式表,您可以定义和准备共享 CSS 样式,然后将这些样式轻松应用于多个阴影根或文档,而不会出现重复内容。对共享 CSSStyleSheet 的更新将应用于已采用它的所有根,并且一旦加载了样式表,对样式表的采用就会变得快速、同步。

由 Constructable 样式表设置的关联适用于许多不同的应用。它可用于提供集中式主题,供许多组件使用:主题可以是传递给组件的 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 RootDocuments 上提供的 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);

综合应用

借助 Constructable StyleSheets,现在网络开发者就有了明确的解决方案来创建 CSS 样式表并将其应用到 DOM 树。我们新增了基于 Promise 的 API,用于从 CSS 来源字符串加载样式表,该字符串使用浏览器的内置解析器和加载语义。最后,我们提供了一种机制,可将样式表更新应用于 StyleSheet 的所有用例,从而简化主题更改和颜色偏好设置等操作。

观看演示

展望未来

此处所述的 API 已随附可构造样式表的初始版本,但我们正在对此进行改进,以使其更易于使用。我们提议使用专门的方法来插入和移除样式表,从而扩展 adoptedStyleSheets FrozenArray,这样就无需克隆数组,并避免可能重复的样式表引用。

更多信息