::开槽的CSS选择器,用于嵌套的子代。

问题描述 投票:0回答:1

CSS ::slotted 选择器选择 <slot> 元素。

然而,当试图选择孙子女时,比如用 ::slotted(*), ::slotted(*) *::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>

请注意为什么跨度没有得到边框。

这是预期的行为吗?我没能找到具体的文档。

如果是,有什么方法可以解决这个问题吗?

html css css-selectors custom-element
1个回答
3
投票

TL;DR

  • 开槽的内容仍然在lightDOM中,是一个很好的选择。反映<slot>

  • ::slotted(*) 只能 目标 的lightDOM 皮肤简单的 选择器


是的,我知道 ::slotted() 不对嵌套元素进行样式设计是预期行为。

嵌套元素的背景

术语 slotted 是反直觉的,它意味着元素lightDOM是 感动 到影子DOM

开槽的lightDOM是 未动在LightDOM中,它仍然是......隐藏的,内容是 反映<slot></slot>

或从 谷歌开发者文档

从概念上讲,分布式节点看起来有点怪异。槽并没有物理地移动DOM,而是在影子DOM内部的另一个位置渲染。

我使用的术语是 反映 而不是 渲染 因为 渲染 意味着你可以访问它 shadowDOM。你不可以,因为插槽式内容不是 影子DOM...才 反映 从lightDOM。


为什么:slotted的功能有限

W3C标准讨论的主要收获(@hayatoito)。此处此处)是。

https:/developer.mozilla.orgen-USdocsWebCSS::slotted。

所以由于性能问题

:slotted( S ) 得到了有限的CSS选择器功能。

  • ►它只需要简单的S选择器 --> 基本上任何带空格的东西都不能用。

  • ►它只针对lightDOM 肌肤. --换言之,只有第一级。

    • ::slotted(h1)::slotted(p) 作品

    • ::slotted(.foo) 作品

    • ::slotted(span) (或任何更深层次的东西)将无法工作(不是一个。肌肤 元素)

<my-element>
  <h1>Hello World</h1> 
  <p class=foo>
    <span>....</span>
  </p>
  <p class=bar>
    <span>....</span>
  </p>
</my-element>

变通办法

变通方法#1--style lightDOM。

<span> 被隐藏在lightDOM中,在那里所做的任何改变都将继续保持在 反映 到其 开槽 表示。

这意味着你可以应用任何你想要的造型。在主DOM中使用CSS (如果你包装了一个父阴影DOM容器,则是一个父阴影DOM容器) <my-element> 一体化)

 <style>
  my-element span {
    .. any CSS you want
  }
 <style>

注意: ::slotted([Simple Selector]) 确认具体性规则,但(简单)不符合: 不增不减 到lightDOM 肌肤 选择器,所以永远不会得到更高的特异性。您 可能 需要 !important 在一些(罕见的)用例中。

 <style>
  ::slotted(H1) {
    color: blue !important;
  }
 <style>

变通方法#2 - 将lightDOM移到shadowDOM上

如果你 移动 lightDOM与 appendChildappend (或insertBefore或cloneNode等)从lightDOM到shadowDOM,你可以做所有你想要的样式。

如果不使用 <slot></slot>:slotted()

变通方法#3 - ::part (影子部件)

(不妨称之为变通)它是一种不同的强大的方式来样式shadowDOM内容。

苹果终于在2020年3月的Safari 13.1中实现了这一点。

见。

注意事项 ::part 款式 影子DOM, <slot></slot> 内容保留在 lightDOM!


参考文献

要注意:可能包含v0文档


相关的SO答案。WCSLOT


PS

  super();
  const shadowRoot = this.attachShadow({mode: 'open'})
  shadowRoot.innerHTML =

都可以链为。

  super()
    .attachShadow({mode: 'open'})
    .innerHTML =

因为 super() 返回 thisattachShadow 回归 this.shadowRoot

© www.soinside.com 2019 - 2024. All rights reserved.