无缝可重用样式。
可构造样式表是在使用 Shadow DOM 时创建和分发可重用样式的一种方法。
一直以来都可以使用 JavaScript 创建样式表。然而,从历史来看,这个过程是使用 <style>
元素和 document.createElement('style')
创建样式表,然后访问其 sheet 属性以获取对底层 CSSStyleSheet 实例的引用。此方法可能会产生重复的 CSS 代码及其相关的膨胀,并且无论是否存在膨胀,附加行为都会导致未样式内容闪烁。 CSSStyleSheet
接口是一组 CSS 表示接口的根,这些接口统称为 CSSOM,它提供了一种以编程方式操作样式表的方法,并消除了与旧方法相关的问题。
可构造样式表使得定义和准备共享 CSS 样式成为可能,然后可以轻松地将这些样式应用于多个 Shadow Root 或文档,而不会产生重复。对共享 CSSStyleSheet 的更新将应用于已采用它的所有根,并且一旦加载了工作表,采用样式表的速度很快且是同步的。
可构造样式表建立的关联非常适合许多不同的应用程序。它可用于提供许多组件使用的集中主题:主题可以是传递给组件的 CSSStyleSheet
实例,对主题的更新会自动传播到组件。它可用于将 CSS 自定义属性值分发到特定的 DOM 子树,而无需依赖于层叠。它甚至可以用作浏览器 CSS 解析器的直接接口,从而可以轻松地预加载样式表,而无需将其注入 DOM 中。
构造样式表
与其引入新的 API 来完成此操作,不如说 可构造样式表规范使得可以通过调用 CSSStyleSheet()
构造函数以命令式方式创建样式表。生成的 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..."
使用构造的样式表
可构造样式表引入的第二个新功能是 adoptedStyleSheets 属性,该属性在 Shadow Root 和 文档上可用。这使我们可以显式地将 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);
整合在一起
借助可构造样式表,Web 开发人员现在拥有一个显式解决方案,用于创建 CSS StyleSheets 并将其应用于 DOM 树。我们有了一个新的基于 Promise 的 API,用于从 CSS 源代码字符串加载 StyleSheets,该 API 使用浏览器的内置解析器和加载语义。最后,我们有了一种将样式表更新应用于 StyleSheet 所有用法的机制,从而简化了诸如主题更改和颜色首选项之类的操作。
展望未来
可构造样式表的初始版本随此处描述的 API 一起发布,但是正在进行的工作使其更易于使用。有一个提案,用于使用专用于插入和删除样式表的方法扩展 adoptedStyleSheets
FrozenArray,这将消除对数组克隆的需求,并避免潜在的重复样式表引用。