在 shadow root 中修改自定义元素的样式

Emi*_*Chu 1 html javascript css shadow-dom custom-element

我正在尝试使用 shadow DOM 修改两个自定义 HTML 元素“输出屏幕”和“自定义计算器”的样式。

当我尝试通过附加如下所示的 shadow DOM 来执行此操作时,未应用样式。任何想法我做错了什么?

JS小提琴

<custom-calculator id="calculator">
  <output-screen></output-screen>
</custom-calculator>

<script>
var o = Object.create(HTMLElement.prototype);
    var oElement = document.registerElement('output-screen', {
        prototype: o
    });

var c = Object.create(HTMLElement.prototype);
var cElement = document.registerElement('custom-calculator', {
  prototype: c
});

var calc = document.querySelector('#calculator')
calc.attachShadow({ mode: 'open' });
calc.shadowRoot;
calc.shadowRoot.innerHTML = `
<style>
output-screen{
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}
custom-calculator {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}
</style>
`;
</script>
Run Code Online (Sandbox Code Playgroud)

Sup*_*arp 5

为了给承载 Shadow DOM 的元素设置样式,在这里<custom-calculator>,您必须使用 de:host伪类(而不是custom-calculator在 Shadow DOM 中是未知的)。

:host {
  display:inline-block;
  background-color:grey;
  width:100%;
  height:100vh;
  vertical-align:top;
}
Run Code Online (Sandbox Code Playgroud)

因为 Shadow DOM 将替换/恢复正常的 DOM 树(此处<output-screen>),所以您必须使用<slot>在 Shadow DOM 中插入/显示它。

calc.shadowRoot.innerHTML = `
  <style>
    ...
  </style>
  <slot></slot>`
Run Code Online (Sandbox Code Playgroud)

然后,为了对<slot>元素所显示的/在元素中显示的内容进行样式设置,您必须使用::slotted()伪元素:

::slotted( output-screen ){
  display:inline-block;
  background-color:orange;
  width:50%;
  height:100vh;
}
Run Code Online (Sandbox Code Playgroud)

现场示例:

:host {
  display:inline-block;
  background-color:grey;
  width:100%;
  height:100vh;
  vertical-align:top;
}
Run Code Online (Sandbox Code Playgroud)
calc.shadowRoot.innerHTML = `
  <style>
    ...
  </style>
  <slot></slot>`
Run Code Online (Sandbox Code Playgroud)