class MyElement extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({mode: 'open'})
shadow.appendChild(document.createTextNode('Yadda blah'))
const span = document.createElement('span')
span.appendChild(document.createTextNode('Can I style U?'))
shadow.appendChild(span)
}
}
customElements.define('my-element', MyElement)
my-element {
border: 1px solid black;
}
span {
font-weight: bold;
}
<my-element></my-element>
如您所见,my-element
具有样式,但是span
中使用的my-element
没有样式。甚至在样式表中说my-element span {font-weight: bold;}
都不会使任何样式有效。
是否可以将样式应用于此span
?
答案 0 :(得分:1)
这是影子dom的预期行为。由于您的HTML看起来像<my-element></my-element>
,因此可以从CSS定位my-element
,但是span
并不是实际dom的一部分,因此您无法定位它。
您只能在阴影dom上下文中将样式应用于span
。
在这种情况下,有更好的方法来定义css,但是为了说明一点,以下内容将样式应用于span
,而不是my-element
:
class MyElement extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({mode: 'open'})
shadow.appendChild(document.createTextNode('Yadda blah'))
const span = document.createElement('span')
span.appendChild(document.createTextNode('Can I style U?'))
shadow.appendChild(span)
const styleTag = document.createElement('style')
styleTag.innerHTML = `
my-element {
border: 1px solid black;
}
span {
font-weight: bold;
}
`
shadow.appendChild(styleTag)
}
}
customElements.define('my-element', MyElement)
<my-element></my-element>
答案 1 :(得分:0)
您必须将样式应用于阴影DOM。一种常见但即将过时的技术是在阴影DOM中添加一个<style>
元素,并将其文本内容设置为您要在自定义元素中应用的CSS。
下面的代码片段就是这样做的。样式保存到变量中,但是只要您知道其上下文运行的频率,就可以将其放置在任何位置。遵循Intervalia的建议,最好使用:host
将样式应用于自定义元素。
也可以改为添加<link>
元素,但这可能会导致该元素弹出而没有样式(FOUC)
const myElementStyle = `
:host {
border: 1px solid black;
}
span {
font-weight: bold;
}
`
class MyElement extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({mode: 'open'});
const style = document.createElement('style');
style.textContent = myElementStyle;
shadow.appendChild(style);
shadow.appendChild(document.createTextNode('Yadda blah'));
const span = document.createElement('span');
span.appendChild(document.createTextNode('Can I style U?'));
shadow.appendChild(span);
}
}
customElements.define('my-element', MyElement)
<my-element></my-element>
另一种选择是使用可构造样式表,该样式表应很快在现代浏览器中可用。这些使您可以创建一个样式表对象,该对象可以嵌入样式或从外部资源导入样式。
我写了一个答案here,所以我只发布一个片段来回答您的问题:
const customSheet = new CSSStyleSheet();
customSheet.replaceSync(`
:host {
border: 1px solid black;
}
span {
font-weight: bold;
}
`);
class MyElement extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({
mode: 'open'
})
shadow.adoptedStyleSheets = [customSheet];
shadow.appendChild(document.createTextNode('Yadda blah'))
const span = document.createElement('span')
span.appendChild(document.createTextNode('Can I style U?'))
shadow.appendChild(span)
}
}
customElements.define('my-element', MyElement)
<my-element></my-element>