簡體   English   中英

外部的 Shadow DOM 樣式

[英]Shadow DOM styling from the outside

我正在尋找一種從外部設置 shadow DOM 樣式的方法。 例如,我想將所有“span.special”元素中所有文本的顏色設置為紅色。 包括來自 shadow DOM 的“span.special”元素。 我怎么能做到這一點?

以前有::shadow偽元素和/deep/組合器又名>>>用於此目的。 所以我可以寫一些類似的東西

span.special, *::shadow span.special {
    color: red
}

但現在::shadow/deep/>>>已被棄用。 那么,我們有什么可以替代它們呢?

好吧,如果您正在使用無法更改的庫 Web 組件,@import 不是解決方案......

最后我找到了幾種方法:

1) 級聯。 Shadow DOM 的宿主元素的樣式也會影響 Shadow DOM 元素。 如果您需要為 Shadow DOM 的特定元素設置樣式,則不是一個選項,而不是每個元素。

2) 自定義屬性https://www.polymer-project.org/1.0/docs/devguide/styling如果 Web 組件的作者提供了這樣的屬性。

3) 在 Polymer 中,也有自定義 Mixins https://www.polymer-project.org/1.0/docs/devguide/styling

4) @import,但僅適用於非庫組件

所以,有幾種可能性,但都是有限的。 沒有像 ::shadow 那樣強大的外部造型方法。

您可以使用@import css,如this answer to another question on SO中所述。

將規則包含在陰影樹中style元素中。

 <style>
   @import url( '/css/external-styles.css' )
 </style>

請注意, >>>組合器仍然是 CSS 范圍模塊草案的一部分。

我確實嘗試了很多方法,包括這里描述的方法。 由於我使用的是外部 Web 組件庫,因此我無權修改這些組件。 因此,對我querySelector的唯一解決方案是使用 JS querySelector ,如下所示:

document.querySelector("the-element.with-shadow-dom")
  .shadowRoot.querySelector(".some-selector").setAttribute("style", "color: black");

不是最好的解決方案,不適合大型樣式,但確實適用於小裝飾。

@John 這已經用 Chrome 83.0.4103.116 測試過(仍將在 Safari 中測試),我為 Ionic (v5) ion-toast組件做了測試。 這是我使用的(幾乎)真實代碼:

  import { toastController } from '@ionic/core';

  let toastOpts = {
    message: "Some message goes here.",
    cssClass: "toast-with-vertical-buttons",
    buttons: [
      {
        text: "Button 1",
        side: 'end'
      },
      {  
        text: "Button2",
        side: 'end'
      },
      {
        icon: "close",
        side: "start"
      }
    ]
  }
  toastController.create(toastOpts).then(async p => {
    let toast = await p.present(); // this renders ion-toast component and returns HTMLIonToastElement
    toast.shadowRoot.querySelector('div.toast-button-group-end').setAttribute("style", "flex-direction: column");
  });

仍然沒有簡單的方法可以刺穿陰影根部,但是您可以通過以下 3 種方法進行操作。 請記住,您需要在 Web 組件內部進行更改。

  1. 使用變量 v1 - 您將需要傳遞該屬性並在 Web 組件內使用該變量。

  2. 使用變量 v2 - 您將需要使用 Web 組件內的變量。

  3. 使用::part() - 您需要將 part 屬性添加到要在 Web 組件中設置樣式的元素。 (注意:這個偽元素得到了很好的支持,但仍處於實驗模式,所以在生產中使用它之前請確保你知道這一點)。

運行下面的代碼示例以獲取詳細信息。

 const elA = document.querySelector('custom-container-a'); const shadowRootA = elA.attachShadow({mode:'open'}); shadowRootA.innerHTML = '<style>:host([border]) {display:block;border: var(--custom-border);}</style>'+ '<p>Shadow content A</p>' const elB = document.querySelector('custom-container-b'); const shadowRootB = elB.attachShadow({mode:'open'}); shadowRootB.innerHTML = '<style>p {display:block;color: var(--custom-color, blue);}</style>'+ '<p>Shadow content B</p>' const elC = document.querySelector('custom-container-c'); const shadowRootC = elC.attachShadow({mode:'open'}); shadowRootC.innerHTML = '<p part="paragraph">Shadow content C</p>'
 /* Normal way of styling */ p { color: orange; } /* Using variables version 1 */ custom-container-a { --custom-border: 3px solid gold; } /* Using variables version 2 */ custom-container-b { --custom-color: green; } /* Using ::part() NOTE: The specs for this hasn't been finalized. So it might not be a good idea to use in production. */ custom-container-c::part(paragraph) { color: magenta; }
 <p>Light content</p> <custom-container-a border></custom-container-a> <custom-container-b></custom-container-b> <custom-container-c></custom-container-c>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM