如何在#shadow-root ( shadow DOM ) 中重新设计元素

Pav*_*nta 3 html css shadow-dom

以下代码是来自 chrome 开发工具的视图

<textarea>
   #shadow-root (user-agent)
     <p> This I want to restyle </p>
 <textarea>
Run Code Online (Sandbox Code Playgroud)

如果我想在 shadow DOM 中重新设置元素的样式,我必须使用什么 CSS 选择器?

谢谢你

Int*_*lia 6

ShadowDOM 旨在防止 CSS 泄漏到 shadowDOM 或从 shadowDOM 泄漏。它是一种替代品<iframe>,对其具有相同的限制。里面的任何 CSS <iframe>都不能影响外面的内容,外面<iframe>的 CSS<iframe>不能影响里面的内容<iframe>

但是您可以使用以下选项之一来影响内部 CSS:

以下选项均不适用于现有 HTML 元素。这些示例仅适用于您编写的自定义元素。

在 shadowDOM 中设置元素样式的第一种方法是将样式与内容一起放置在 shadowDOM 中。

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode:'open'}).innerHTML = `
    <style>
      p { background-color: #A00; color: white; }
    </style>
    <p>inner content</p>`;
  }
}

customElements.define('my-el', MyEl);
Run Code Online (Sandbox Code Playgroud)
<my-el></my-el>
Run Code Online (Sandbox Code Playgroud)

第二种更有限的方法是使用 CSS 变量:

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode:'open'}).innerHTML = `
    <style>
      p { background-color: var(--bgcolor, #A00); color: var(--color, white); }
    </style>
    <p>inner content</p>`;
  }
}

customElements.define('my-el', MyEl);
Run Code Online (Sandbox Code Playgroud)
body {
  --bgcolor: yellow;
  --color: navy;
}
Run Code Online (Sandbox Code Playgroud)
<my-el></my-el>
Run Code Online (Sandbox Code Playgroud)

第三种方式,也是有限的,是通过属性或属性:

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode:'open'}).innerHTML = `
    <p>inner content</p>`;
  }
  
  set bgColor(val) {
    this.shadowRoot.querySelector('p').style.backgroundColor = val;
  }

  set color(val) {
    this.shadowRoot.querySelector('p').style.color = val;
  }
}

customElements.define('my-el', MyEl);

const myEl = document.querySelector('my-el');
myEl.bgColor = '#090';
myEl.color = 'white';
Run Code Online (Sandbox Code Playgroud)
<my-el></my-el>
Run Code Online (Sandbox Code Playgroud)