可构造样式表 - 通过javascript来生成css的新方式
可构造样式表是一种使用Shadow DOM进行创建和分发可重用样式的新方法。
使用Javascript来创建样式表是可能的。然而,这个过程在历史上一直是使用document.createElement('style')来创建<style>元素,然后通过访问其sheet属性来获得一个基础的CSSStyleSheet实例的引用。这种方法可以生成重复的CSS,其会使得代码极速膨胀。无论是否存在臃肿,这种附加的动作会导致未样式化内容的闪烁。CSSStyleSheet接口是CSS集合的根,被称为CSSOM,提供一种程序化的方法去控制样式,还有就是消除相关联的旧代码的问题。
可构造的样式表可以定义和准备共享的CSS样式,然后轻松的吧这些样式应用到多个Shadow Roots中或者是文档中,且无需重复。修改CSSStyleSheet以后,其相关联的样式也都会被改变。并且一旦加载了样式表,其新样式会很快且同步的加载到页面中。
由Constructable Stylesheets创建的关联很适合许多不同的应用程序。它可以被用于在多个不同的组件间提供一个集中的主题:主题可以传递到组件的是CSSStyleSheet的实例,当主题改变以后,会自动传递给组件。它可以不依赖样式表,吧自定义CSS属性分发给特定的DOM子树中。它甚至可以直接用于浏览器解析器直接的接口,无需将他们注入到DOM就可以很轻易的加载样式表。
构建一个样式表
与引入一个新API不同,可构造样式表规范使得其可以通过调用CSSStyleSheet()构造函数来强制创建样式表。CSSStyleSheet对象的结果有两个方法,这俩方法会使样式表更安全的被添加和修改,其操作不会触发无格式内容的闪光(FOUC)。replace()会返回一个Promise,一旦有外部引用(@import)被加载就会解析。而replaceSync()不允许外部引用。
const sheet = new CSSStyleSheet();// replace all styles synchronously: sheet.replaceSync('a { color: red; }');// this throws an exception:try { sheet.replaceSync('@import url("styles.css")');} catch (err) { console.error(err); // imports are not allowed}// replace all styles, allowing external resources: sheet.replace('@import url("styles.css")') .then(sheet => { console.log('Styles loaded successfully'); }) .catch(err => { console.error('Failed to load:', err); });
使用可构造样式表
由可构造样式表引入的第二个新功能是Shadow Roots和Documents中的adoptedStyleSheets属性。这允许我们显式的将由CSSStyleSheet定义的属性应用到给定的DOM子树中。为此,我们将属性设置为一个具有一个或者多个样式表的数组,以用于该元素。
// Create our shared stylesheet:const sheet = new CSSStyleSheet(); sheet.replaceSync('a { color: red; }');// Apply the stylesheet to a document: document.adoptedStyleSheets = [sheet];// Apply the stylesheet to a Shadow Root:const node = document.createElement('div');const shadow = node.attachShadow({ mode: 'open' }); shadow.adoptedStyleSheets = [sheet];
注意我们是覆盖了adoptedStyleSheets的值,而不是改变了数组的值。这是必要的,因为这个数组是被冻结的。像push()那样改变值会抛出一个异常,所以我们必须赋值一个新数组。为了保留通过adoptedStyleSheets添加的已经存在样式表。我们可以使用合并数组的方式来创建一个新数组,这个数组包含已经存在的旧样式,和新添加的新样式。
const sheet = new CSSStyleSheet(); sheet.replaceSync('a { color: red; }');// Combine existing sheets with our new one: document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
总结
由于可构造样式表,网站开发人员现在有一个创建CSS样式表并且把他们应用到DOM树中的一个明确的解决方案。我们有了一个新的基于Promise的API,用于从使用浏览器内置解析器和加载语义的CSS源字符串中加载样式表。最终,我们有一种机制,可以将样式表更新应用于StyleSheet的所有用法,从而简化主题更改和颜色首选项等操作。
展望未来
可构建样式表的初始版本附带了此处描述的API,但正在开展工作以使事情更容易使用。 有人建议使用专用方法扩展adoptStyleSheets FrozenArray以插入和删除样式表,这样就不需要进行数组克隆并避免可能的重复样式表引用。
翻译自:
相关推荐
background-color: blue;background-color: yellow;<input type="button" value="变蓝" @click="changeColorT