Men*_*ndy 17 css css-selectors web-component shadow-dom custom-element
CSS::slotted选择器选择<slot>元素的子元素。
但是,当尝试选择像 with ::slotted(*), ::slotted(*) *, or那样的孙子时,选择::slotted(* *)器似乎没有生效。
class MyElement extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({mode: 'open'})
    shadowRoot.innerHTML = `
      <style>
        ::slotted(*) {
          display: block;
          border: solid blue 1px;
          padding: 3px;
        }
        ::slotted(*) span {
          display: block;
          border: solid red 1px;
          padding: 3px;
        }
        ::slotted(* span) {
          display: block;
          border: solid green 1px;
          padding: 3px;
        }
      </style>
      <slot></slot>
    `;
  }
}
customElements.define('my-element', MyElement);<my-element>
  <p>
    <span>Test</span>
  </p>
</my-element>请注意跨度如何没有边界。
这是预期的行为吗?我无法为此找到具体的文档。
如果是,有没有办法解决这个问题?
Dan*_*man 34

TL; 博士
::slotted 规范:https : //drafts.csswg.org/css-scoping/#slotted-pseudo
开槽内容遗体在光 DOM,被反射到一个<slot>在阴影 DOM
::slotted(x)以 lightDOM 外部元素(又名“皮肤”)为目标,而不是shadowDOM 中的 SLOT
::slotted(x)采用基本选择器
可继承的样式渗入 shadowDOM 
https://lamplightdev.com/blog/2019/03/26/why-is-my-web-component-inheriting-styles/
有关 SLOT 和相关主题的最新 WHATWG 讨论,请参阅
是的,::slotted()不对嵌套元素设置样式是预期行为。
这个术语slotted是违反直觉的,
它意味着元素 lightDOM 被移动到 shadowDOM
开槽的 lightDOM不会移动,它仍然......隐藏......在 lightDOM 中
,内容(如果开槽)被反射到<slot></slot>
或来自Google 开发者文档
, .
'; .
我使用术语反射而不是渲染,因为渲染意味着您可以在shadowDOM 中访问它。
你不能,因为开槽内容不是在shadowDOM ......仅反映从lightDOM。
尝试了更高级的 shadowDOM 样式。
WebComponents 版本 0 (v0) 具有<content>和::content;但它已从规范中删除:https : 
//developer.mozilla.org/en-US/docs/Web/HTML/Element/content
W3C 标准讨论的主要内容
(@hayatoito(谷歌团队)在这里和这里)是:

所以在 V1 中,我们有:slotted:https : //developer.mozilla.org/en-US/docs/Web/CSS/ :: slotted
来自 Mozilla 开发者 Emilio:
来源:https : //github.com/w3c/webcomponents/issues/889
性能问题是它增加了每个节点需要去寻找影响它们的规则的子树的数量。
现在的逻辑是这样的:如果你被打入了插槽,根据需要遍历你的插槽并在它们的影子树中收集规则。这是代码 这很好,因为元素样式的复杂性直接取决于您正在构建的阴影树的复杂性,并且它只影响开槽节点。
如果您想允许组合子经过时隙,那么每个节点都需要查看其祖先链和前兄弟链,并查看其中的哪些是时隙的,然后对它们的所有时隙执行该过程。然后,最重要的是,您还需要更改一般选择器匹配代码,以便如果您不在正确的影子树中,则不包含带槽选择器的选择器将不匹配。
这是您为所有元素支付的成本,无论您是使用 Shadow DOM 还是 ::slotted,而且可能只是不会飞。
:slotted( S ) 获得有限的 CSS 选择器功能:? 它只需要简单的 S 选择器。 --> 基本上任何有空格的东西都不起作用
? 它只针对 lightDOM 'skin'。--> 也就是说,只有一级
<my-element>
  <h1>Hello World</h1> 
  <p class=foo>
    <span>....</span>
  </p>
  <p class=bar>
    <span>....</span>
  </p>
</my-element>
::slotted(h1)和::slotted(p)作品
::slotted(.foo) 作品
::slotted(span)(或任何更深的东西)将不起作用(不是“皮肤”元素)
注意: ::slotted([Simple Selector])确认Specificity 规则,
但(简单)不会增加lightDOM皮肤选择器的权重,因此永远不会获得更高的Specificity。在某些(罕见的)用例中
您可能需要!important。
 <style>
  ::slotted(H1) {
    color: blue !important;
  }
 <style>
该<span>隐藏在lightDOM,所作的任何更改也将继续反映其开槽表示。
这意味着您可以在主 DOM 中使用 CSS应用您想要的任何样式
(或者如果您包装<my-element>在一个父 shadowDOM 容器中)
 <style>
  my-element span {
    .. any CSS you want
  }
 <style>
如果您使用以下命令将lightDOM移动到shadowDOM:this.shadowRoot.append(...this.childNodes)
你可以在 shadowDOM<style>标签中做你想要的所有样式。
注意:您现在不能再使用<slot></slot>和:slotted()了。
<slot>s仅适用于从 lightDOM反射的内容。
有关元素将自身包裹在额外的 shadowDOM 层中的示例,
因此没有CSS 溢出,并且<slot>s可以使用,请参阅:
这是一种不同/强大的 shadowDOM 内容样式方式:
Apple 终于在 2020 年 3 月的 Safari 13.1 中实现了 shadowParts
看:
笔记! ::part样式shadowDOM,
<slot></slot>内容保留在lightDOM 中!
请注意:可能包含 v0 文档!
https://css-tricks.com/encapsulating-style-and-structure-with-shadow-dom/
https://developers.google.com/web/fundamentals/web-components/shadowdom?hl=en#composition_slot
https://polymer-library.polymer-project.org/2.0/docs/devguide/style-shadow-dom#style-your-elements
https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/slotchange_event
::part() - https://developer.mozilla.org/en-US/docs/Web/CSS/::part
更改 buttonclick 上的插槽名称并反映 lightDOM 中的内容:
<my-element>
  <h1>Hello World</h1> 
  <p class=foo>
    <span>....</span>
  </p>
  <p class=bar>
    <span>....</span>
  </p>
</my-element>
| 归档时间: | 
 | 
| 查看次数: | 3447 次 | 
| 最近记录: |