gpt4 book ai didi

css -::slotted CSS选择器,用于shadowDOM中的嵌套子级

转载 作者:行者123 更新时间:2023-12-03 14:34:52 25 4
gpt4 key购买 nike

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>


请注意跨度如何不获得边界。

这是预期的行为吗?我无法为此找到具体的文档。

如果是,是否有解决此问题的方法?

最佳答案

在shadowDOM中设置:: slotted元素的样式

TL; DR

  • 插入的内容中保留,在 DOM
  • <slot>以lightDOM外层元素(也称为“皮肤”)为目标,不是 shadowDOM中的SLOT
  • ::slotted(x)采用简单选择器
  • 可继承样式滴入shadowDOM
    https://lamplightdev.com/blog/2019/03/26/why-is-my-web-component-inheriting-styles/
  • 有关SLOT和相关主题的最新WHATWG讨论,请参阅https://github.com/whatwg/html/issues/6051#issuecomment-816971072
    参与者: rniwa (Apple), annvk (Mozilla), dominic (Google)

  • 背景
    是的, ::slotted(x)不设置嵌套元素的样式是预期的行为。
    术语 ::slotted()是违反直觉的,
    这表示元素lightDOM已被 移至odtDOM

    slotted lightDOM is NOT moved, it remains.. hidden.. in lightDOM
    the content (IF slotted) is reflected to a <slot></slot>


    或来自Google Developer Documentation

    𝘾𝙤𝙣𝙘𝙚𝙥𝙩𝙪𝙖𝙡𝙡𝙮, 𝙙𝙞𝙨𝙩𝙧𝙞𝙗𝙪𝙩𝙚𝙙 𝙣𝙤𝙙𝙚𝙨 𝙘𝙖𝙣 𝙨𝙚𝙚𝙢 𝙖 𝙗𝙞𝙩 𝙗𝙞𝙯𝙖𝙧𝙧𝙚.
    𝙎𝙡𝙤𝙩𝙨 𝙙𝙤𝙣'𝙩 𝙥𝙝𝙮𝙨𝙞𝙘𝙖𝙡𝙡𝙮 𝙢𝙤𝙫𝙚 𝘿𝙊𝙈; 𝙩𝙝𝙚𝙮 𝙧𝙚𝙣𝙙𝙚𝙧 𝙞𝙩 𝙖𝙩 𝙖𝙣𝙤𝙩𝙝𝙚𝙧 𝙡𝙤𝙘𝙖𝙩𝙞𝙤𝙣 𝙞𝙣𝙨𝙞𝙙𝙚 𝙩𝙝𝙚 𝙨𝙝𝙖𝙙𝙤𝙬 𝘿𝙊𝙈.


    我使用术语反射(reflect)而不是渲染,因为渲染意味着您可以在
    shadowDOM中访问它
    您不能,因为在
    shadowDOM中插入的内容不是 ...只有反射(reflect)了lightDOM中的

    为什么:slotted功能有限
    尝试了更高级的shadowDOM样式。
    WebComponents版本0(v0)具有slotted<content>;但已将其从规范中删除:
    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/content
    W3C标准讨论的主要内容
    (@hayatoito(Google团队)herehere)是:

    因此在V1中,我们有::content:https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

    添加#1:如果允许:: slotted用于复杂选择器,则性能
    来自Mozilla开发人员Emilio:
    资料来源:https://github.com/w3c/webcomponents/issues/889

    The performance issue is that it increments the amount of subtrees inwhich every node needs to go look for rules that affect to them.

    Right now the logic goes like: if you're slotted, traverse your slotsand collect rules in their shadow trees as needed. This is the codeThis is nice because the complexity of styling the elementdepends directly on the complexity of the shadow trees that you'rebuilding, and it only affects slotted nodes.

    If you want to allow combinators past slotted then every node wouldneed to look at its ancestor and prev-sibling chain and look at whichones of them are slotted, then do that process for all their slots.Then, on top, you also need to change the general selector-matchingcode so that selectors that do not contain slotted selectors don'tmatch if you're not in the right shadow tree.

    That's a cost that you pay for all elements, regardless of whether youuse Shadow DOM or ::slotted, and is probably just not going to fly.



    所以由于性能问题:slotted的CSS选择器功能受到限制:
  • ►它只需要S的简单选择器。->基本上任何带有空格的东西都行不通
  • ►它仅针对lightDOM '皮肤'。 ->换句话说,只有第一级
  • <my-element>
    <h1>Hello World</h1>
    <p class=foo>
    <span>....</span>
    </p>
    <p class=bar>
    <span>....</span>
    </p>
    </my-element>
  • :slotted( S )::slotted(h1)有效
  • ::slotted(p)可以工作
  • ::slotted(.foo)(或更深层次的任何内容)将不起作用(不是'皮肤'元素)

  • 注意: ::slotted(span)会确认“特异性”规则,
    但是(简单)不会将重量添加到lightDOM 皮肤选择器中,因此永远不会获得更高的特异性。
    在某些(很少)用例中,您可能需要::slotted([Simple Selector])
     <style>
    ::slotted(H1) {
    color: blue !important;
    }
    <style>

    样式化槽位内容
    另请参阅:Applying more in depth selection to the :host CSS pseudo class
    #1-样式lightDOM!important隐藏在lightDOM中,在那里进行的任何更改将继续反射(reflect)到其带槽的表示中。
    这意味着您可以在主DOM
    中将所需的 样式与CSS一起应用
    (如果您将<span>包装在其中,则为父shadowDOM容器)
     <style>
    my-element span {
    .. any CSS you want
    }
    <style>
    例如,元素将本身包裹到一个额外的shadowDOM层中,
    请参阅:https://jsfiddle.net/CustomElementsExamples/Lhcsd2m5/?slotmeister
    #2-(解决方法)将lightDOM移至shadowDOM
    如果您移动 lightDOM shadowDOM:<my-element>您可以在shadowDOM this.shadowRoot.append(...this.children)标签中进行所需的所有样式设置。
    注意:您现在不能再使用<style><slot></slot>。这仅适用于lightDOM内容。
    例如,元素将本身包裹到一个额外的shadowDOM层中,
    请参阅:https://jsfiddle.net/CustomElementsExamples/Lhcsd2m5/?slotmeister
    #3-:: part(阴影部分)
    这是设置shadowDOM内容样式的另一种/强大的方法:
    苹果终于在2020年3月的Safari 13.1中实现了shadowParts
    看:
  • https://meowni.ca/posts/part-theme-explainer/
  • https://css-tricks.com/styling-in-the-shadow-dom-with-css-shadow-parts/
  • https://dev.to/webpadawan/css-shadow-parts-are-coming-mi5
  • https://caniuse.com/mdn-html_global_attributes_exportparts

  • 注意! :slotted()样式shadowDOM,::part内容仍保留在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://github.com/w3c/webcomponents/issues/331
  • https://github.com/w3c/webcomponents/issues/745
  • https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/slotchange_event
  • ::part()-https://developer.mozilla.org/en-US/docs/Web/CSS/::part

  • 示例:使用插槽作为路由器
    更改buttonclick上的广告位名称,然后反射(reflect)lightDOM中的内容:

    <template id=MY-ELEMENT>
    <style>
    ::slotted([slot="Awesome"]){
    background:lightgreen
    }
    </style>
    <slot><!-- all unslotted content goes here --></slot>
    <slot id=answer name=unanswered></slot>
    </template>
    <style>/* style all IMGs in lightDOM */
    img { max-height: 165px;border:3px dashed green }
    img:hover{ border-color:red }
    </style>
    <my-element><!-- content below is: lightDOM! -->
    SLOTs are: <button>Cool</button> <button>Awesome</button> <button>Great</button>
    <span slot=unanswered>?</span>
    <div slot=Cool> <img src="https://i.imgur.com/VUOujQT.jpg"></div>
    <span slot=Awesome><b>SUPER!</b></span>
    <div slot=Awesome><img src="https://i.imgur.com/y95Jq5x.jpg"></div>
    <div slot=Great> <img src="https://i.imgur.com/gUFZNQH.jpg"></div>
    </my-element>
    <script>
    customElements.define('my-element', class extends HTMLElement {
    connectedCallback() {
    this.attachShadow({mode:'open'})
    .append(document.getElementById(this.nodeName).content.cloneNode(true));
    this.onclick = (evt) => {
    const label = evt.composedPath()[0].innerText; // Cool,Awesome,Great
    this.shadowRoot.getElementById("answer").name = label;
    }
    }
    });
    </script>

    关于css -::slotted CSS选择器,用于shadowDOM中的嵌套子级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61626493/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com