将样式导入Web组件的规范方法是什么?
以下给我一个错误HTML element <link> is ignored in shadow tree
:
<template>
<link rel="style" href="foo.css" />
<h1>foo</h1>
</template>
我使用shadow DOM使用以下方法插入它:
var importDoc, navBarProto;
importDoc = document.currentScript.ownerDocument;
navBarProto = Object.create(HTMLElement.prototype);
navBarProto.createdCallback = function() {
var template, templateClone, shadow;
template = importDoc.querySelector('template');
templateClone = document.importNode(template.content, true);
shadow = this.createShadowRoot();
shadow.appendChild(templateClone);
};
document.registerElement('my-nav-bar', {
prototype: navBarProto
});
现在直接在影子dom中支持<link>
标签。
可以直接使用:
<link rel="stylesheet" href="yourcss1.css">
<link href="yourcss2.css" rel="stylesheet" type="text/css">
它已被whatwg和W3C批准。
在阴影dom中使用css的有用链接:
直接css链接可用于阴影dom。
如果您需要在<template>
标签内放置外部样式,您可以尝试
<style> @import "../my/path/style.css"; </style>
但我觉得这将在元素创建后开始导入。
NB!
这个答案已经过时了
请通过下面的Himanshu Sharma检查答案
最新答案:https://stackoverflow.com/a/48202206/2035262
Polymer允许您在
<polymer-element>
定义中包含样式表,这是Shadow DOM本身不支持的功能。
这是一个有点奇怪的参考,但我不能直接google。看起来目前没有关于支持模板内部链接的传闻。
也就是说,无论你是否想要使用vanilla web组件,你都应该使用<style>
标签内联你的css,或者在javascript中手动加载和应用你的css。
这是一个新功能,允许构建CSSStyleSheet
对象。这些可以使用JavaScript从css文件设置或导入其内容,并应用于文档和Web组件的影子根。它将在Chrome版本73中提供,并且可能在不久的将来用于Firefox。
有一个good writeup on the Google developers site,但我将在下面简要总结一下,底部有一个例子。
您可以通过调用构造函数来创建新工作表:
const sheet = new CSSStyleSheet();
可以通过调用方法replace
或replaceSync
来应用样式。
replaceSync
是同步的,不能使用任何外部资源:
sheet.replaceSync(`.redText { color: red }`);
replace
是asynchronous,可以接受引用外部资源的@import
语句。请注意,replace
返回需要相应处理的Promise
。
sheet.replace('@import url("myStyle.css")')
.then(sheet => {
console.log('Styles loaded successfully');
})
.catch(err => {
console.error('Failed to load:', err);
});
可以通过设置adoptedStyleSheets
或shadow DOM的document
属性来应用该样式。
document.adoptedStyleSheets = [sheet]
adoptedStyleSheets
中的数组是冻结的,不能使用push()
进行变异,但是您可以通过结合其现有值进行连接:
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
shadow DOM可以以相同的方式从文档的adoptedStyleSheets
继承构造的样式:
// in the custom element class:
this.shadowRoot.adoptedStyleSheets = [...document.adoptedStyleSheets, myCustomSheet];
请注意,如果在构造函数中运行此组件,则组件将仅继承在创建之前采用的样式表。在adoptedStyleSheets
中设置connectedCallback
将在连接时为每个实例继承。值得注意的是,这不会导致FOUC。
让我们创建一个名为x-card
的组件,它将文本包装在一个风格漂亮的div
中。
// Create the component inside of an IIFE
(function() {
// template used for improved performance
const template = document.createElement('template');
template.innerHTML = `
<div id='card'></div>
`;
// create the stylesheet
const sheet = new CSSStyleSheet();
// set its contents by referencing a file
sheet.replace('@import url("xCardStyle.css")')
.then(sheet => {
console.log('Styles loaded successfully');
})
.catch(err => {
console.error('Failed to load:', err);
});
customElements.define('x-card', class extends HTMLElement {
constructor() {
super();
this.attachShadow({
mode: 'open'
});
// apply the HTML template to the shadow DOM
this.shadowRoot.appendChild(
template.content.cloneNode(true)
);
// apply the stylesheet to the shadow DOM
this.shadowRoot.adoptedStyleSheets = [sheet];
}
connectedCallback() {
const card = this.shadowRoot.getElementById('card');
card.textContent = this.textContent;
}
});
})();
<x-card>Example Text</x-card>
<x-card>More Text</x-card>
尝试<style>
中的<template>
元素:
<template>
<style>
h1 {
color: red;
font-family: sans-serif;
}
</style>
<h1>foo</h1>
</template>